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

MyMemoWiki

「Java EE JNDI ENC 注入」の版間の差分

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

2020年2月16日 (日) 04:27時点における最新版

Java EE JNDI ENC 注入

Java EE |

  • アプリケーションサーバーにデプロイされたすべての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デプロイメント記述子も利用可能

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

JNDI ENCへの投入方法

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

XMLによる投入

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

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

  • アノテーションで定義された情報で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デプロイメント記述子で<jnjection-target> を利用できる
<ejb-jar>
  <enterprise-bean>
    <session>
      <ejb-name>MyEJB</ejb-name>
      <ejb-local-ref>
        <ejb-ref-name>ejbs/referenceToMyEJB2</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <local>org.ejb3book.example.MyEJB2LocalBusiness</local>
        <ejb-link>MyEJB2</ejb-link>
        <injection-target>
          <injection-target-class>
            org.ejb3book.example.MyEJBBean
          </injection-target-class>
          <injection-target-name>otherBean</injection-target-name>
        </injection-target>
      </ejb-local-ref>
    </session>
  </enterprise-bean>
</ejb-jar>

XMLによるオーバーライド

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

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

注入と継承

  • 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が注入される

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

参照の注入と型