4

現在のインスタンスが、必要な会話に関連付けられたものを処理するために使用されているものであるCDI conversationことを知っているだけで、プログラムでインスタンスを取得することは可能ですか? そして、可能であればどのように?threadCDI request

特に、私がやりたいことはこれです:

@ConversationScoped
public class UnitOfWork {...}

public class Client {
    @Inject transient UnitOfWork uof;
...
}

public class Room {
    @Inject transient UnitOfWork uof;
...
}

uofただし、 @Inject アノテーションを適用する代わりに、プログラムによるメカニズムを使用してインスタンス変数を初期化します (ClientRoomはエンティティであり、注入をサポートしていないため)。 私はすでに、次の静的メソッドによって取得されたa
を使用して を注入しようとしました:UnitOfWorkBeanManager

public static <B> B getManagedBean(Class<B> type, Annotation... qualifiers) {
    try {
        BeanManager beanManager = InitialContext.doLookup("java:comp/BeanManager");
        Set<Bean<?>> beans = beanManager.getBeans(type, qualifiers);
        Bean<B> bean = (Bean<B>) beanManager.resolve(beans);
        CreationalContext<B> cc = beanManager.createCreationalContext(bean);
        return bean.create(cc);
    } catch (NamingException e) {
        throw new RuntimeException("", e);
    }
}

しかし、問題は、上記のメソッドによって与えられた Bean が新しいものであり (呼び出しごとに新しいインスタンスが与えられる)、それが必要でClientありRoom、同じ会話スコープのUnitOfWork.

4

2 に答える 2

2

申し訳ありませんが、本当の答えではありませんが、コメントを書くには多すぎます:

エンティティが依存性注入をサポートしないのには理由があります。これは主に、エンティティのライフサイクルが管理対象Beanのライフサイクルから切り離されているためです。

エンティティでのDIのユースケースは確かに見られますが、このアプローチの利点がリスクを上回っているかどうかを2倍(および3倍)チェックします。ある種の第2レベルのキャッシュ地獄で永続コンテキストをハッキングしていることに気付くかもしれません;)

于 2012-09-05T09:19:56.293 に答える
1

答えは非常に近かったのですが、見落としていました。はい、BeanManager を使用して、アクティブなコンテキスト (現在のスレッドに関連付けられているコンテキスト) に含まれる任意の Bean の Bean クラス インスタンスを取得できます。このメソッドは仕事をします:

public static <B> B getContextualBeanInstance(Class<B> type, Annotation... qualifiers) {
    try {
        BeanManager beanManager = InitialContext.doLookup("java:comp/BeanManager");
        Set<Bean<?>> beans = beanManager.getBeans(type, qualifiers);
        Bean<?> bean = beanManager.resolve(beans);
        CreationalContext<?> cc = beanManager.createCreationalContext(bean);
        return (B) beanManager.getReference(bean, type, cc);
    } catch (NamingException e) {
        throw new RuntimeException("", e);
    }
}

質問の投稿で述べた方法との唯一の違いは、これがBeanManager#getReference(..)の代わりに使用することですBean#create(..)

typeパラメータ化された Bean タイプをサポートする場合は、パラメータのタイプを から に変更しClass<B>ますType

Bean が @Dependent スコープである場合、Bean クラス インスタンスの破棄を処理して、メモリ リークを回避する必要があります。ここでは、きれいにそれを行う方法を説明します。

于 2013-02-06T01:58:27.153 に答える