CDIの@Producesアノテーションについて読んだことがありますが、その使用法がわかりません。
public class Resources {
// Expose an entity manager using the resource producer pattern
@SuppressWarnings("unused")
@PersistenceContext
@Produces
private EntityManager em; //
@Produces
Logger getLogger(InjectionPoint ip) { //
String category = ip.getMember()
.getDeclaringClass()
.getName();
return Logger.getLogger(category);
}
@Produces
FacesContext getFacesContext() { //
return FacesContext.getCurrentInstance();
}
}
以下から取得: http://www.jboss.org/jdf/quickstarts/jboss-as-quickstart/guide/GreeterQuickstart/#GreeterQuickstart-
コンテナはどのようにしてプロデューサーメソッドを呼び出すことを知っていますか? EntityManagerを注入する場合、コンテナはどのようにして@produces EntityManagerを呼び出しますか?そして、getLoggerプロデューサーメソッドはどのように呼び出されますか?
また、すべてのトラブルを経験する理由もわかりません。
CDI仕様 のセクション3.3は、 @Produces
アノテーションの使用に関するかなり高レベルの概要を示しています。
プロデューサーメソッドは、注入されるオブジェクトのソースとして機能します。
•注入されるオブジェクトは、Beanのインスタンスである必要はありません。または
•注入されるオブジェクトの具体的なタイプは、実行時に異なる場合があります。
•オブジェクトには、Beanコンストラクターによって実行されないカスタム初期化が必要です。
たとえば、JavaエンティティマネージャなどのEE管理コンポーネントと他のCDIコンポーネントをブリッジしたい場合、@Produces
アノテーションを利用できます。データドメインレイヤー全体で@PersistenceContext
アノテーションを複製する必要がなくなります。
class A {
@PersistenceContext // This is a JPA annotation
@Produces // This is a CDI 'hook'
private EntityManager em;
}
class B {
@Inject // Now we can inject an entity manager
private EntityManager em;
}
別の便利な使用法は、CDIフレンドリBeanを持たないライブラリを回避することです(たとえば、デフォルトコンストラクターがない)。
class SomeTPLClass {
public SomeTPLClass(String id) {
}
}
class SomeTPLClassProducer {
@Produces
public SomeTPLClass getInstance() {
return new SomeTPLClass("");
}
}
プロデュースのJavadocは、後で他のマネージドBeanにインジェクトできる名前付きコレクションを作成するという興味深い(ただし非常にまれなケース)を示しています(非常にクールです)。
public class Shop {
@Produces @ApplicationScoped
@Catalog @Named("catalog")
private List<Product> products = new LinkedList<Product>(8);
//...
}
public class OrderProcessor {
@Inject
@Catalog
private List<Product> products;
}
コンテナは、@ Producesアノテーションでマークされたすべてのメソッドとフィールドの処理を担当し、通常、アプリケーションのデプロイ時にこれを行います。処理されたメソッドとフィールドは、必要に応じて、マネージドBeanの注入ポイント解決の一部として使用されます。
この例は私にとってはうまくいきませんでした。ちょっとした調整はちょっとした微調整でした:
@Alternative
class SomeTPLClass {
public SomeTPLClass(String id) {
}
}
class SomeTPLClassProducer {
@Produces
public SomeTPLClass getInstance() {
return new SomeTPLClass("");
}
}
そのため、クラスに@ Alternativeを追加して、@ Defaultに2つのオプションがあったというエラーを取り除く必要がありました。