web-dev-qa-db-ja.com

@ Inject、@ EJB、@ Local、@ Remote、@ LocalBeanなど:混乱していますか?

次の構成があります。

  • 1つのEAR GF EJBコンポーネントを持つ2つのEJB-JARを含む。
  • 別のGlassfishサーバーでの1つのWAR(=>他のJVM)EJBコンポーネントにアクセスするWebコンポーネントを含む。

EARの各EJB-JARには2つのEJBビジネスサービスがあり、それらはすべて次のように開発されています。

@Remote
public interface ServiceAItf {
    ...
}

@Stateless
@Local
public class ServiceAImpl implements ServiceAItf {
    ...
}

私のWARでは、明示的な方法でEJBコンポーネントにアクセスします 「InitialContext.lookup」 リモートインターフェイス上。

私のEARでは、パフォーマンス、アーキテクチャなどの点で、注入のベストプラクティスについてかなり混乱しています...

次の質問があります。

  • ご覧のとおり、注釈を宣言しました "@地元" ローカルインターフェイスを定義せずにサービスを実装します。それが正しいか?少なくとも、展開時にエラーはありません。しかし、多分私は使用する必要があります 「@LocalBean」 代わりに注釈?私は 「@LocalBean」 注釈は、単に実装を直接呼び出すことを可能にします "地元" EJB。ただし、次のようにコードで実装を使用する必要があります。

    @Stateless @LocalパブリッククラスServiceBImplはServiceBItfを実装します{@EJB private ServiceAImpl serviceA; ...}

  • あるEJBを別のEJBに注入する最良の方法は何ですか? それはこのように動作します:

    @Stateless @LocalパブリッククラスServiceBImplはServiceBItfを実装します{@EJB private ServiceAItf serviceA; ...}

しかし、私が気づいたことから、注入された「serviceA」はリモートプロキシであり、同じEARファイル内の同じJVMにあります。そのため、パフォーマンスに影響があると思います。それが私がこのようなサービスを注入しようとした理由です:

@Stateless
@Local
public class ServiceBImpl implements ServiceBItf {
    @Inject
    private ServiceAItf serviceA;
    ...
}

しかし、GFでは機能しません。次の例外があります。

WELD-001408 Unsatisfied dependencies for type [...] ...

次に、ローカルインターフェイスを作成しようとしましたが、アノテーション「@Inject」によるインジェクションは、両方のサービスで機能します

このようなローカルインターフェイスを作成しても、サービスはアノテーションを介して注入されません 「@Inject」 しかしnullです:

@Local
public interface ServiceALocalItf {
    ...
}

使用することが強く推奨される多くの記事を読みました 「@Inject」 の代わりに 「@EJB」 ローカル呼び出し用の場合。それは次の質問に私を導きます:その場合 "@地元" EJB呼び出しが推奨されます(または単に使用されます)?

このすべての分析の後、次の結論に達しました。

  • サービスごとに、 "@地元" と 「@Remote」 インターフェース。
  • WARからEARのEJB-JARまで、リモートインターフェースへのJNDIルックアップを行います。
  • EJB-JARからEJB-JARへ、経由でインジェクションを行う 「@EJB」 ローカルインターフェースへ。
  • 同じEJB-JAR内の2つのサービスの場合、「@ Inject」を介してローカルインターフェイスにインジェクションを行います。

あなたはそれについてどう思いますか?それが正しいか?

36
Blaise Gosselin

ご覧のとおり、ローカルインターフェースを定義せずに、サービス実装でアノテーション「@Local」を宣言しました。それが正しいか?

EJB 3.1では、ローカルインターフェイスの要件がなくなりました。明示的に必要な場合を除き、それらを記述する必要はありません。

あるEJBを別のEJBに注入する最良の方法は何ですか?

ここに書くことのカップル:

Java EE 6、Java Enterpriseが変更されました。新しいJSRは、いわゆるマネージドBean(JSFマネージドBeanと混同しないでください)依存性注入とライフサイクル管理の観点からコンテナの恩恵を受けることができる一種の最小コンポーネントとして。これは、コンポーネントと「ジャスト」がある場合DIを使用し、コンテナがそのライフサイクルを制御できるようにする場合、EJBを使用する必要がないneed。次の場合のみ-トランザクション処理、プーリング、パッシベーション、クラスタリングなどのEJB機能が明示的に必要です。

これにより、あなたの質問に対する答えは3つの部分に分かれます。

  1. @EJBではなく@Injectを使用します。CDIの概念は(a)すべての管理対象Bean(EJBを含む)で機能し、(b)ステートフルであり、したがって純粋な@EJB DIよりもはるかに優れています。
  2. コンポーネントにEJBが必要ですか?
  3. CDIを見るのは間違いなく価値があります ドキュメント
22
jan groth

@Inject注釈はJava beans(POJOs)に使用され、@EJB注釈はエンタープライズJava Beanに使用されます。コンテナが@EJB注釈によって提供されるejbを別のBeanは、ejbのライフサイクルも制御し、ステートレスBeanのプーリングなどを実行します(注入されるBeanがデプロイされない場合、参照はnullになります)@Inject注釈CDIメカニズムを使用する場合は、単に注入されたインスタンスを見つけて作成しますnew演算子のようなリソース(注入されるインターフェースの実装が存在しない場合、参照はnullになります。)@Inject注釈付きの修飾子を使用して、注入されるインターフェースの異なる実装を選択できます。

0
maks