4

インターフェイスの実装として、CDI に代替クラスを「ピックアップ」させたいと考えています。

すべてが EAR にバンドルされていますが、代替実装は war ファイルにあり、残り (インターフェイスを注入するクラス、インターフェイス、インターフェイスの「デフォルト」実装) は ejb jar にあります。

これを説明するコードを次に示します。

EJB モジュール:

public interface I {}

 

public class C implements I {}

 

public class A {
  @Inject I var

  public void test() {
    System.out.println(var instanceof C); // I want to have here as Result: false
  }
}

戦争モジュール:

@Alternative
public class D implements I {}

war ファイルに beans.xml を設定しても解決しませんでした。

4

2 に答える 2

7

あなたが説明している構造では、目的の注射を得る方法はありません。

EJB クラスローダは WAR 内のクラスにアクセスできないため、インジェクションは代替実装を考慮しません。

EAR 構造を変更し、別の (D) を lib/jar に apppropriare と共に配置する場合は、解決策が可能ですbeans.xml。D クラスが EJB および WAR から見えるようになり、注入は必要に応じて行われます。

編集

あなたが投稿したソリューションは、私がここで説明していますが、ほとんど機能しています。

EAR
  - ejb-module-1.jar 
     - A.class (@Inject I)
     - I.class
     - C.class (@Stateless implements I)
     - META-INF/beans.xml
  - ejb-module-2.jar
     - D.class (@Alternative @Stateless implements I)
     - META-INF/beans.xml (<alternatives><class>D</class></alternative>)
  - app.war
     - calls A.test()
     - WEB-INF/beans.xml

beans.xml唯一の問題は、 alternative 宣言の場所を間違えたことです。

CDI 仕様 (1.1、ただし以前の実装にも適用可能) の第 5.1 章では、次のように述べられています。

モジュールが Bean アーカイブであり、代替がその Bean アーカイブで明示的に選択されていない限り、モジュール内のクラスまたは JSP/JSF ページへのインジェクション、ルックアップ、または EL 解決に代替は使用できません。

つまり、 bean を使用するクラスの同じモジュールで代替を選択する必要があります。

改訂された(そして作業中の)構造は次のとおりです。

EAR
  - ejb-module-1.jar 
     - A.class (@Inject I)
     - I.class
     - C.class (@Stateless implements I)
     - META-INF/beans.xml (<alternatives><class>D</class></alternative>)
  - ejb-module-2.jar
     - D.class (@Alternative @Stateless implements I)
     - META-INF/beans.xml (empty <beans></beans>)
  - app.war
     - calls A.test()
     - WEB-INF/beans.xml (empty <beans></beans>)

また、標準の Bean の場合、代替の選択は のモジュールに対してのみ機能しますが、代替は で宣言されbeans.xmlますが、EJB には同じことは当てはまりません。したがって、D代替案 (being @Stateless) はアプリケーション全体で有効です。

于 2013-07-03T21:40:50.773 に答える
2

CDI 1.1 以降。@Priority を使用して、代替がグローバルコンテキストで検出されるようにすることができます-ここを参照してください依存性注入とプログラムによる検索

また、@Priority を使用する場合は、beans.xml で代替を宣言する必要はありません。CDIアプリケーションでの代替の使用はこちらを参照してください。

于 2016-06-09T14:15:48.143 に答える