web-dev-qa-db-ja.com

@EJBsアノテーションは何をしますか?

私はこの構造が何をするかを大体知っています。SomeTypeEJBを作成し、オブジェクトを別のEJBに注入します。

 @EJB(name="name1")
 SomeType someVariable

これで、次のように始まるクラスができました:(関連するのは@EJBsだけだと思いますが、すべてのクラスレベルの注釈を付けます)

@Remote(SomeClass.class)
@Stateless(name="someName")
@EJBs({@EJB(name="name1",beanInterface=Type1.class),
       @EJB(name="name2",beanInterface=Type2.class)})
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@TransactionManagement(TransactionManagementType.CONTAINER)
public class X extends Y{ 
  //code

@EJB sはここで何をしますか?彼らはおそらくJNDIから「name1」...オブジェクトを取得または作成しますが、結果はどこに配置しますか?近くに.lookup呼び出しはありませんが、コードベースが大きいため、これについてはよくわかりません。

ボーナス質問:2つの@Transactionアノテーションは単にデフォルトを繰り返すと思いますか?

UPDATE:この時点で、@EJBsは独自の拡張であると主張する複数の人。そうではない。これはJava EE5。詳細については JavaDocを参照してください。 。個々の@EJBのコンテナです。注釈。

これらのEJBアノテーションを主張するすべての人が検索を行うと信じています。このルックアップの結果がどうなるかを知りたいだけです。

38
hyperman

_@EJB_注釈(および_@Resource_、_@WebServiceRef_など)は2つの目的を果たします。

  1. コンポーネントの名前空間で参照を宣言します。たとえば、@EJB(name="myEJB")は、参照_Java:comp/env/myEJB_を作成します。フィールドに注釈を付けて名前を指定しない場合、参照_Java:comp/env/com.example.MyClass/myField_が作成されます。
  2. アノテーションがフィールドまたはセッターメソッドで宣言されている場合、コンテナはコンポーネントの作成時にインジェクションを実行します。

参照がlookup("Java:comp/env/myEJB")のために解決されているか、注入のために解決されているかに関係なく、参照が解決される方法は異なります。

  1. EE 6+を使用する場合、lookup属性には、ターゲットを解決するためのJNDIルックアップが必要です。
  2. 一部のアプリケーションサーバーはmappedNameをサポートしています。これはベンダー固有であると指定されています。これは通常、ルックアップを実行することで実装されます。
  3. アプリケーションサーバーは、展開時にバインディングをサポートします。これは通常、ルックアップを実行することで実装されます。
  4. 他のバインディング情報が提供されておらず、Beanインターフェース(beanInterfaceまたはフィールドタイプ)がアプリケーション内の単一のEJBによってのみ実装されている場合、EJB仕様はそれにフォールバックすることを要求します。
  5. 他のバインディング情報が提供されず、#4が機能しない場合、一部のアプリケーションサーバーはref名に基づいてサーバー名前空間でルックアップを実行しようとします(たとえば、_Java:comp/env/myEJB_はmyEJBのルックアップを引き起こす可能性がありますサーバーの名前空間で)。
39
Brett Kail

Miljen Mikicの答えは、可能な答えについてのアイデアを与えてくれました。 JNDIを知っている人がこれを読んでいるなら、私が基本的にここで推測しているように、これが正しいかどうか教えてください。

基本的に、JNDIツリーを調べる方法は2つあります。グローバルパス(/ some/proprietary/path/my/bean)とプログラムの環境(Java:comp/env/my/bean)のいずれかです。これは、グローバルパスからローカル環境への参照を作成し、そこからコンポーネントを検索するという考え方です。

@Ejb(name = "Java:comp/env/my/bean"、mappedName = "/ some/proprietary/path/my/bean")は、この参照をJava code(記述子xmlファイルなし)。

これは、@ Ejb(name = "Java:comp/env/my/bean")がそれ自体で何もしないことを意味します。つまり、参照を自分自身にコピーします。副作用として、コンパイル時にこの参照が必要であることをアプリケーションサーバーが認識しているという事実に悪影響を与える可能性がありますが、それはそれについてです。

2
hyperman

この link によれば、基本的にこのアノテーションにより、EJBはコンテキストに関連して外部EJBを検索できます。通常、それを行うよりエレガントな方法があります。

1
Miljen Mikic

ボーナスの質問に関して:はい、トランザクションに関する2つのアノテーションはデフォルトを繰り返しています:デフォルトのTransactionManagementTypeはCONTAINER(vs BEAN)であり、-default-TransactionAttributeType REQUIREDは、トランザクションコンテキスト内でBeanが呼び出された場合、トランザクションが継続されることを単に示しています。そうしないと、新しいトランザクションが開始されます(たとえば、常に新しいtxを作成するREQUIRES_NEWとは対照的です)。これは実際には、Cfに聞こえるほど些細なことではなく、詳細です。 EJB 3.1仕様:

「13.3.7 Beanのメソッドのトランザクション属性の仕様

コンテナ管理のトランザクション境界を持つエンタープライズBeanのBeanプロバイダーは、エンタープライズBeanのメソッドのトランザクション属性を指定できます。デフォルトでは、コンテナ管理のトランザクション境界を持つBeanのメソッドのトランザクション属性の値はREQUIREDトランザクション属性であり、この場合、トランザクション属性を明示的に指定する必要はありません。[...] "

1
William Adams