| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

Java EE JNDI ENC 注入

提供: MyMemoWiki
2020年2月16日 (日) 04:27時点におけるPiroto (トーク | 投稿記録)による版
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)
ナビゲーションに移動 検索に移動

Java EE JNDI ENC 注入

Java EE |

  • アプリケーションサーバーにデプロイされたすべてのEJBコンテナは、Enterprise Naming Context(ENC) と呼ばれる独自の内部レジストリを持っている
  • これはJNDIで実装されている

グローバルJNDI

  • EJB3.1ではSLSB、SFSBのビューは以下の構文のグローバルJNDIで入手出来る必要がある
  1. java:global[/app-name]/module-name/bean-name [!FQN]
項目 内容
app-name アプリケーション(またはEAR)名(オプション)
module-name モジュール(JARまたはWAR)名
FQN 完全修飾インターフェース名

利点

  • ベンダにかかわらず、同じ場所でEJBを見つけることができ移植性がある

改善できる点

  • ルックアップコードはベンダー固有の JNDI Context の取得に依存
  • キャストが必要で、タイプセーフではない
  • 自分でJNDI名を作成するため、間違えやすい

EJBコンテナは一連のタイプセーフな注入メカニズムを提供

  • 多くの場合、利用可能な参照を取得するのに必要なのは以下だけ
  1. @EJB
  2. MyEJBLocalBusiness bean;

JNDI ENC

  • EJB3.xでは、ENCが強化され、JNDI ENC参照をBeanクラスのフィールドに直接注入できるようになった
  • このためにアノテーションが主に利用されるがm,XMLデプロイメント記述子も利用可能

<blockquote>EJB、インターフェースへの参照、JMSキューまたはトピックの送信先、JMS接続ファクトリ、データソース、JCAリソース、プリミティブ型など、様々なものをENCに登録できる</blockquote>

JNDI ENCへの投入方法

  • 2つの異なる方法で設定できる

XMLによる投入

  • ejb-local-ref:MyEJBがMyEJB2のローカルビジネスインターフェースへの参照を必要としていることをEJBコンテナに通知
  • ejbs/referenceToMyEJB2 という名前でJNDI ENC に登録
  1. <ejb-jar>
  2. <enterprise-bean>
  3. <session>
  4. <ejb-name>MyEJB</ejb-name>
  5. <ejb-local-ref>
  6. <ejb-ref-name>ejbs/referenceToMyEJB2</ejb-ref-name>
  7. <ejb-ref-type>Session</ejb-ref-type>
  8. <local>org.ejb3book.example.MyEJB2LocalBusiness</local>
  9. <ejb-link>MyEJB2</ejb-link>
  10. </ejb-local-ref>
  11. </session>
  12. </enterprise-bean>
  13. </ejb-jar>

アノテーションによる設定

  • アノテーションで定義された情報でJNDI ENCに投入
  1. @Stateful(name="MyEJB")
  2. @EJB(name="ejbs/referenceToMyEJB2",beanInterface=MyEJB2LocalBusiness.class,beanName="MyEBJ2")
  3. public class MyEJBBean implements MyEJBLocalBusiness {
  4. :
  5. }

ENCからの参照方法

  • JNDI ENCに登録したものはすべて、java:comp/env コンテキストから名前で検索できます
  • compはcomponent を表している
  1. try {
  2. javax.naming.InitialContext ctx = new InitialContext();
  3. bean = (MyEJB2LocalBusiness)ctx.lookup("java:comp/env/ejbs/referenceToMyEJB2");
  4. } catch(javax.naming.NamingException ne) {
  5. :
  6. }

EJBContext

  • EJBContextにはENCルックアップメソッドがあり、チェック例外を発生させず、相対名を使う
  • SessionContext、MessageDrivenContext いずれも EJBContextを拡張
  1. @Resource
  2. private javax.ejb.SessionContext ctx;
  3. public void hoge() {
  4. MyEJBLocalBusiness bean = ctx.lookup("ejbs/referenceToMyEJB2");
  5. }

アノテーションによる注入

  • ENCルックアップの代わりに、EJB参照をメンバ変数に直接注入できる
  1. @EJB
  2. private MyEJB2LocalBusiness bean;
  • セッターメソッドを使った注入もサポート
  • フィールドに直接注入するより冗長だが、単体テストで簡単にモックできるというメリット
  1. @EJB
  2. public void setBean(final MyEJB2LocalBusiness bean) {
  3. this.bean = bean;
  4. }

デフォルトENC名

  • Beanクラスのフィールドやセッターメソッドにアノテーションをつけると、注入された要素のためにJNDI ENCにエントリーを作成することにもなる
  • これらはすべての環境アノテーションで起こるが、@EBJでは、注入アノテーションのname()属性が指定されていると、参照はその名前でENCに格納される
  • 名前が指定されない場合、ENC名はアノテーションづけされたフィールドやメソッドの完全修飾クラス名とフィールド名やメソッドのベース名から付けられる
  1. org.ejb3book.example.MyEJBBean/otherBean
EJB参照(上記例は以下で検索できる)
  1. java:comp/env/org.ejb3book.example.MyEJBBean/otherBean

XMLによる注入

  • フィールドの初期化にアノテーションを利用したくない場合、ejb-jar.xmlデプロイメント記述子で<jnjection-target> を利用できる
  1. <ejb-jar>
  2. <enterprise-bean>
  3. <session>
  4. <ejb-name>MyEJB</ejb-name>
  5. <ejb-local-ref>
  6. <ejb-ref-name>ejbs/referenceToMyEJB2</ejb-ref-name>
  7. <ejb-ref-type>Session</ejb-ref-type>
  8. <local>org.ejb3book.example.MyEJB2LocalBusiness</local>
  9. <ejb-link>MyEJB2</ejb-link>
  10. <injection-target>
  11. <injection-target-class>
  12. org.ejb3book.example.MyEJBBean
  13. </injection-target-class>
  14. <injection-target-name>otherBean</injection-target-name>
  15. </injection-target>
  16. </ejb-local-ref>
  17. </session>
  18. </enterprise-bean>
  19. </ejb-jar>

XMLによるオーバーライド

  • 注入アノテーションを使うと、Beanクラスのコードに構成をハードコーディングすることになるとみなされる場合もある
  • EJB仕様ではXMLデプロイメント記述子を使って注入アノテーションをオーバーライドできる

<blockquote>XMLは常にアノテーションメタデータよりも優先される。XMLはハードコーディングされたアノテーションを再構成する手段を提供する</blockquote>

注入と継承

  • Beanクラスをクラス階層に含めることができる
  • 注入アノテーションは特定の注入規則に従う
  1. public class Base {
  2. private SomeInf bean;
  3. @EJB(beanName="SomeEJB")
  4. public void someMethod(SomeInf bean) {
  5. this.bean = bean;
  6. }
  7. }
  1. @Stateless
  2. public class MySessionBean extends Base implements MySessionLocalBusiness {
  3. }
  • 上記例で、Baseを継承する ステートレスセッションBeanは、Baseクラスの someMethodに適切なリソースを注入する。
  1. @Stateless
  2. public class MySessionBean extends Base implements MySessionLocalBusiness {
  3. private SomeInf bean;
  4. @EJB(beanName="AnotherEJB")
  5. public void someMethod(SomeInf bean) {
  6. this.bean = bean;
  7. }
  8. }
  • このようにすると、SomeEJBではなく、AnotherEJBが注入される

<blockquote>someMethod が private の場合、Base には SomeEJBが注入される</blockquote>

参照の注入と型