【发布时间】:2013-12-01 18:13:57
【问题描述】:
在 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)。
【问题讨论】:
-
你的问题有点难以理解。 CDI 对象在运行时注入,并在一定范围内限定。依赖作用域的 bean 总是在注入时新创建,应用程序作用域在应用程序的生命周期内被缓存。也许如果您澄清了一些问题,这将有助于理解您要做什么。
-
我现在唯一能想到的就是保持对 bean 的弱引用(以某种方式监视对 BeanManager 接口的调用以使其可移植)并对字段进行反射。
-
这里没有进展。另一种方法可能是深入带注释的类型,搜索字段以使用我的代理类型切换。
-
我想你可能把问题复杂化了。假设您有一个 POJO,其中包含一些请求数据。为什么不把这个 POJO 注入到任何你想要这个易失数据的地方呢?
-
@John,不确定我是否理解您的建议。我的问题是关于在 CDI 连接类型之前尝试修改类型,以便在注册 bean 后捕获事件。