Java EE アプリケーションによって実行時に生成/ロードされるクラスを次に示します ( @Default Bar
Bean は同じアプリケーションによって提供されます)。
public class Foo {
@PersistenceContext private EntityManager em;
@Resource private UserTransaction tx;
@EJB private MyEJB ejb;
@Inject Bar bar;
public Foo() {
}
@PostConstruct
public void postConstruct () { ... }
public void businessMethod() { ... }
}
インスタンス化する方法は次のとおりです。
import javax.enterprise.inject.spi.Unmanaged;
...
@Inject private BeanManager bm;
...
Class clazz = loadClazz();
Unmanaged unmanaged = new Unmanaged(bm, clazz);
Object obj = unmanaged.newInstance()
.produce()
.inject()
.postConstruct()
.get();
JBoss/WildFly では、EntityManager、EJB、UserTransaction などを含むすべてのフィールドが正しく注入されます。
TomEE と GlassFish では、Java EE リソースは無視され、bar
フィールドのみが注入されます。
- これは TomEE と GlassFish のバグと見なすべきですか、それともアプリケーション サーバーで異なる方法で実装されている JavaEE/CDI 仕様のホワイト スポットにすぎないのでしょうか? GlassFish と WildFly の両方が同じ CDI 実装、つまりJBoss Weldを使用しているため、純粋な CDI の問題ではないことは間違いありません。
- TomEE と GlassFish で上記を達成するにはどうすればよいですか? 移植可能なソリューションが望ましいですが、サーバーに依存するコードの一部は問題ありません (この種の問題では避けられないのではないかと思います)。
全体的な目的は、すべての範囲の CDI インジェクション (単純なものから、など@Inject
の Java EE リソースまで) を動的コードに提供することです。私の最初の試みは、注釈付きフィールド + 動的ビジネス ロジックを組み込むクラスをオンザフライで生成することでした (はい、WildFly でのみ機能しました)。一般的に言えば、次のような一連の動的注入定義があります。@PersistenceContext
@Resource
@EJB
@Annotation(param = "value") @Qualifier1 @Qualifier2 ... Type name;
ここで、、、などAnnotation
のいずれかであり、これが CDI マネージド Bean 内にある場合に注入されたであろうインスタンスを取得したいと考えています。したがって、インジェクション メタデータを受け取り、対応するインスタンスを返す仮説的なメソッドは許容されます。Inject
PersistenceContext
Resource
EJB