次のようなクラスがあるとします。
@Stateless
@Local({ X.class })
public class XBean implements X {
@EJB // name() attribute should by spec default to "foo.XBean/y", but see below
private Y y; // Y is @Local
}
そして他の場所で私が持っている:
@Stateless
@Local({ Y.class })
public class YBean implements Y {}
@Stateless
@Local({ Y.class })
public class UnwantedYBean implements Y {}
ここで、(最小限の XML を使用して、XML 記述子で) のy
フィールドに配置されるものをオーバーライドまたは明示的に指定したいとしますXBean
。
この構成 (META-INF/ejb-jar.xml
もちろんファイル内) は驚くべきことに (私にとって) GlassFish 3.1.2.2では機能しません。
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>XBean</ejb-name>
<ejb-local-ref>
<ejb-ref-name>foo.XBean/y</ejb-ref-name>
<ejb-link>YBean</ejb-link>
</ejb-local-ref>
</session>
</enterprise-beans>
</ejb-jar>
ejb-jar.xml
この質問は、コンテナのバグなどではなく、上記のスニペットに焦点を当てたいと思います。具体的には、上記のスニペットは、どの EJB が自分のフィールドに注入されるかをオーバーライドするための正しく、可能な限り最小の方法ですか?XBean.y
いくつかのメモ:
<injection-target>
他の人は、そこにスタンザを入れる必要があると提案しました。なぜでしょうか?@EJB
注入ターゲットは、注釈を使用することで既に指定されています。注入が行われる場所をオーバーライドしたくはありません。実際に注入されるものだけをオーバーライドします。EJB 仕様の作成者自身も、
<ejb-ref-name>
は単純であるべきでありy
、 ではないと述べていfoo.XBean/y
ます。これは、仕様に次のように記載されているにもかかわらずです (セクション 16.5.1.3)。
ejb-ref-name 要素は、EJB 参照名を指定します。その値は、エンタープライズ Bean コードで使用される環境エントリ名です[強調]。
name
属性のデフォルト値がアノテーション (!) であると述べている EJB 仕様のどこにもありませんが@EJB
、環境エントリ名でもあると推測できます。仕様では、セクション 16.5.1.1 に例が示されています。
package com.acme.example;
@Stateless public class ExampleBean implements Example {
...
@EJB private ShoppingCart myCart;
...
}
@EJB
...これは私のものとまったく同じで、同じセクションで述べています(これは、の属性のデフォルト値が何であるかを発見するのと同じくらい近いname
です):
エンタープライズ Bean 参照は
java:comp/env/com.acme.example.ExampleBean/myCart
、参照 Bean のネーミング コンテキストで名前を持ちます。ここExampleBean
で、 は参照 Bean とcom.acme.example
そのパッケージのクラスの名前です。
その文の「ネーミング コンテキスト」はjava:comp/env/
パーツなので、それ以外はすべて名前です。したがって、飾り気のない@EJB
注釈のname
属性のデフォルト値は ですclassname/fieldName
。そうでなければ、これがどうなるかわかりません。これは、GlassFish EJB FAQにある表によっても裏付けられています。
結論:上記の XML スタンザの何が問題なのですか? のプロキシされたインスタンスがの注釈付きフィールドYBean
に挿入さ れないのはなぜですか?XBean
@EJB
private Y y