1

これは、JSF FacesConverter が CDI の適格な @Inject ターゲットではないという既知の問題の回避策に関連しています。FacesConverter への CDI インジェクションの回避策に従いました。しかし、私の FacesConverter では、オブジェクトの Class をコンストラクターに渡すという機能を利用していました。

javadocから- 「コンバーターに Class インスタンスを受け取る単一引数コンストラクターがあり、変換されるデータの Class がコンバーターのインスタンス化時にわかっている場合、このコンストラクターを使用して、ゼロ引数バージョンの代わりにコンバーターをインスタンス化する必要があります。 ." これは、引数なしまたは @Inject アノテーション付きコンストラクターのみが許可される「通常のスコープ」Bean の CDI 要件と直接競合します。

要約すると、CDI インジェクションを受け取ることができ、実行時に変換されるオブジェクトのクラスにアクセスできるコンバーターを使用したいと考えています。

Weld 2.0.4 を搭載した Glassfish 4 で Mojarra 2.2.4 を使用しています。

4

1 に答える 1

3

この代替案に興味がある人のために、Inject アノテーションを、コンストラクターの BeanManager を介したプログラムによるルックアップに置き換えることができました。凝縮されたコードは以下のとおりです。私はパフォーマンスをテストしていませんが、それがマイナス面であると思われます。時間が許せば、Omnifaces ソリューションと比較します。

編集: BeanManager ルックアップのコストは最小限であることが判明しました。コンストラクターは平均で 1 ミリ秒未満かかります。

@FacesConverter(forClass = AbstractEntity.class)
public class EntityConverter implements Converter {

    private LocationService locationService;
    private Class entityClass;

    //Special parameterized constructor for @FacesConverter described in the original question
    public EntityConverter(Class entityClass) throws NamingException {
            this.entityClass = entityClass;
            this.locationService = loadManagedBean(LocationService.class, "locationService");
        }

    //Generic lookup method for @Named managed beans
    protected <T> T loadManagedBean(Class<T> clazz, String beanName) throws NamingException {
            InitialContext initialContext = new InitialContext();
            BeanManager bm = (BeanManager) initialContext.lookup("java:comp/BeanManager");

            Bean<T> bean = (Bean<T>) bm.getBeans(beanName).iterator().next();
            CreationalContext<T> cc = bm.createCreationalContext(bean);
            T beanInstance = (T) bm.getReference(bean, clazz, cc);
            return beanInstance;
    }
}
于 2013-10-11T19:56:37.513 に答える