0

Arquillian でのテストで Weld 1.1.13.Final を使用する....

フィールドに揮発性の何かを注入するとしましょう。変更されるプロパティのようなもので、注入ポイントを所有する Bean が変更イベントを受け取るようにする必要があります。CDI 拡張機能の作成について考えました。

ProcessAnnotatedType イベントをキャッチし、フィールド インジェクション ポイントにカスタム アノテーションを持つすべてのフィールドを探します。

 <T> void pat(@Observes ProcessAnnotatedType<T> event, BeanManager bm) {
   final AnnotatedType<T> target = event.getAnnotatedType();

   for (AnnotatedField<? super T> field : target.getFields())
     if (field.isAnnotationPresent(Value.class)) {  // ignore that I don't check @Inject here for the moment
        CtClass wrapper = pool.get(target.getJavaClass().getName());
        ConstPool cp = wrapper.getClassFile().getConstPool();

        CtMethod m = CtNewMethod.make(....)
        ....
        wrapper.addMethod(m);

        event.setAnnotatedType(bm.createAnnotatedType(wrapper.toClass()));
     }
 }

その後、フィールドのすべての注入ポイントを取得し、基礎となる WeldField を「ラッパー」タイプに対応する新しいフィールドに置き換えました。そうでない場合、Bean の検証は失敗します。

しかし、これは起動中のセットアップでのみ機能します。たとえば、Arquillian が Bean Manager を使用して「ラップ」の 1 つを注入するクラスを初期化する場合ではありません。Bean Resolver は Type をハッシュ キーとして使用して Bean を検索するため、失敗します。

基本的に、カスタム イベントを受け取るための追加のメソッドを使用して、CDI によって注釈が付けられた (Bean になった) クラスを "マスク" できるとは思いません。クールだったでしょうが、Type は Type です (つまり、equals/hashCode をプロキシまたは偽造する方法がわかりません)。

4

1 に答える 1

0

とった。TypeSafeBeanResolver リゾルバー (少なくとも CDI Weld 実装) 内の計算値関数 (Google 拡張機能) がスマートであることが判明しました。クラスを拡張するだけの場合:

 CtClass wrapper = pool.makeClass(target.getJavaClass().getName()+"Proxy");
 wrapper.setSuperclass(pool.get(target.getJavaClass().getName()));
 .....
 final AnnotatedType<T> other = bm.createAnnotatedType(wrapper
                    .toClass());

その後、すべて正常に動作します。Bean でのイベントのキャプチャをテストしました。コードをコメント付きで Gist に投稿します。

于 2013-12-19T15:07:17.427 に答える