CDI extension, altering processed type

ε祈祈猫儿з 提交于 2020-02-07 05:17:24

问题


Using Weld 1.1.13.Final in test with Arquillian....

Let's say I inject into a field something volatile. Something like a property subject to change that I want the bean owning the injection point to receive change events. Thought about creating a CDI extension.

Caught ProcessAnnotatedType event and looking for all fields that have an custom annotation on field injection points:

 <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()));
     }
 }

Had even grabbed thereafter all the injection points for fields and replaced the underlying WeldField with a new Field corresponding the "wrapper" type. Otherwise bean validation fails.

But this only works for stuff setup during startup not when for example Arquillian uses the Bean Manager to initialize a class that injects one of my "wraps". Things fail since the Bean Resolver uses the Type as a hash key to find beans.

Basically I don't think I can "mask" a class that is annotated (made into a bean) by the CDI with an extra method to receive custom events. Would have been cool but a Type is a Type (i.e. no idea how to proxy or fake the equals/hashCode).


回答1:


Got it. Turns out the compute value function (google extension) inside the TypeSafeBeanResolver resolver (at least the CDI Weld implementation) is smart. If I just extend the class:

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

then everything works fine. Tested capturing an event in a bean. Will post the code on a Gist with a comment.



来源:https://stackoverflow.com/questions/20050437/cdi-extension-altering-processed-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!