!!!Java EE JNDI ENC 注入 [Java EE] {{amazon 4873115086}} *アプリケーションサーバーにデプロイされたすべてのEJBコンテナは、Enterprise Naming Context(ENC) と呼ばれる独自の内部レジストリを持っている *これはJNDIで実装されている !!!グローバルJNDI *EJB3.1ではSLSB、SFSBのビューは以下の構文のグローバルJNDIで入手出来る必要がある java:global[/app-name]/module-name/bean-name [!FQN] ,項目,内容 ,app-name,アプリケーション(またはEAR)名(オプション) ,module-name,モジュール(JARまたはWAR)名 ,FQN,完全修飾インターフェース名 !!利点 *ベンダにかかわらず、同じ場所でEJBを見つけることができ移植性がある !!改善できる点 *ルックアップコードはベンダー固有の JNDI Context の取得に依存 *キャストが必要で、タイプセーフではない *自分でJNDI名を作成するため、間違えやすい !!EJBコンテナは一連のタイプセーフな注入メカニズムを提供 *多くの場合、利用可能な参照を取得するのに必要なのは以下だけ @EJB MyEJBLocalBusiness bean; !!!JNDI ENC *EJB3.xでは、ENCが強化され、JNDI ENC参照をBeanクラスのフィールドに直接注入できるようになった *このためにアノテーションが主に利用されるがm,XMLデプロイメント記述子も利用可能 ""EJB、インターフェースへの参照、JMSキューまたはトピックの送信先、JMS接続ファクトリ、データソース、JCAリソース、プリミティブ型など、様々なものをENCに登録できる !!JNDI ENCへの投入方法 *2つの異なる方法で設定できる !XMLによる投入 *ejb-local-ref:MyEJBがMyEJB2のローカルビジネスインターフェースへの参照を必要としていることをEJBコンテナに通知 *ejbs/referenceToMyEJB2 という名前でJNDI ENC に登録 MyEJB ejbs/referenceToMyEJB2 Session org.ejb3book.example.MyEJB2LocalBusiness MyEJB2 !アノテーションによる設定 *アノテーションで定義された情報でJNDI ENCに投入 @Stateful(name="MyEJB") @EJB(name="ejbs/referenceToMyEJB2",beanInterface=MyEJB2LocalBusiness.class,beanName="MyEBJ2") public class MyEJBBean implements MyEJBLocalBusiness { : } !!ENCからの参照方法 *JNDI ENCに登録したものはすべて、java:comp/env コンテキストから名前で検索できます *compはcomponent を表している try { javax.naming.InitialContext ctx = new InitialContext(); bean = (MyEJB2LocalBusiness)ctx.lookup("java:comp/env/ejbs/referenceToMyEJB2"); } catch(javax.naming.NamingException ne) { : } !EJBContext *EJBContextにはENCルックアップメソッドがあり、チェック例外を発生させず、相対名を使う *SessionContext、MessageDrivenContext いずれも EJBContextを拡張 @Resource private javax.ejb.SessionContext ctx; public void hoge() { MyEJBLocalBusiness bean = ctx.lookup("ejbs/referenceToMyEJB2"); } !アノテーションによる注入 *ENCルックアップの代わりに、EJB参照をメンバ変数に直接注入できる @EJB private MyEJB2LocalBusiness bean; *セッターメソッドを使った注入もサポート *フィールドに直接注入するより冗長だが、単体テストで簡単にモックできるというメリット @EJB public void setBean(final MyEJB2LocalBusiness bean) { this.bean = bean; } !デフォルトENC名 *Beanクラスのフィールドやセッターメソッドにアノテーションをつけると、注入された要素のためにJNDI ENCにエントリーを作成することにもなる *これらはすべての環境アノテーションで起こるが、@EBJでは、注入アノテーションのname()属性が指定されていると、参照はその名前でENCに格納される *名前が指定されない場合、ENC名はアノテーションづけされたフィールドやメソッドの完全修飾クラス名とフィールド名やメソッドのベース名から付けられる ::例 org.ejb3book.example.MyEJBBean/otherBean ::EJB参照(上記例は以下で検索できる) java:comp/env/org.ejb3book.example.MyEJBBean/otherBean !XMLによる注入 *フィールドの初期化にアノテーションを利用したくない場合、ejb-jar.xmlデプロイメント記述子で を利用できる MyEJB ejbs/referenceToMyEJB2 Session org.ejb3book.example.MyEJB2LocalBusiness MyEJB2 org.ejb3book.example.MyEJBBean otherBean !XMLによるオーバーライド *注入アノテーションを使うと、Beanクラスのコードに構成をハードコーディングすることになるとみなされる場合もある *EJB仕様ではXMLデプロイメント記述子を使って注入アノテーションをオーバーライドできる ""XMLは常にアノテーションメタデータよりも優先される。XMLはハードコーディングされたアノテーションを再構成する手段を提供する !注入と継承 *Beanクラスをクラス階層に含めることができる *注入アノテーションは特定の注入規則に従う public class Base { private SomeInf bean; @EJB(beanName="SomeEJB") public void someMethod(SomeInf bean) { this.bean = bean; } } @Stateless public class MySessionBean extends Base implements MySessionLocalBusiness { } *上記例で、Baseを継承する ステートレスセッションBeanは、Baseクラスの someMethodに適切なリソースを注入する。 @Stateless public class MySessionBean extends Base implements MySessionLocalBusiness { private SomeInf bean; @EJB(beanName="AnotherEJB") public void someMethod(SomeInf bean) { this.bean = bean; } } *このようにすると、SomeEJBではなく、AnotherEJBが注入される ""someMethod が private の場合、Base には SomeEJBが注入される !!参照の注入と型