CDI扩展,改变处理类型

时间:2013-11-18 14:39:48

标签: cdi weld

在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初始化一个注入我的“包裹”之一的类。事情失败,因为Bean Resolver使用Type作为哈希键来查找bean。

基本上我不认为我可以通过CDI“掩盖”一个注释(制作成bean)的类,并使用额外的方法来接收自定义事件。本来很酷但Type是一个Type(即不知道如何代理或伪造equals / hashCode)。

1 个答案:

答案 0 :(得分:0)

知道了。原来TypeSafeBeanResolver解析器(至少CDI Weld实现)内的计算值函数(谷歌扩展)是智能的。如果我只是扩展课程:

 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上。