CDI 项目中的 @AroundInvoke
有3个项目使用CDI。项目A有一个用于事务控制的拦截器。
项目 B 使用项目 A 将数据保存在数据库中。当我运行这些单元测试时,一切都通过了。
项目 C 使用项目 B 进行集成测试。当它从 Interceptor 找到 @AroundInvoke 注释时,这些测试将失败。
出了什么问题?拦截器仅位于项目 B beans.xml 中。
异常堆栈跟踪并没有理清我的思路。它只显示 jassist 错误。调试,发现问题出在Weld内部的boostrap.deploybeans()。因此,我在拦截器类中评论了 @AroundInvoke,测试一切正常,但在数据库上插入。我认为发生这种情况是因为我删除了为插入创建事务的拦截器。
代码:
1)有一个项目A,定义了一个注解以及该注解的拦截器。示例:
/Annotation/
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Transactional {
}
/Interceptor/
@Interceptor
@Transactional
public class TransactionalInterceptor implements Serializable {
…
@AroundInvoke
public Object intercept(InvocationContext context) throws Exception {
…
}
…
}
我认为这个项目必须有一个空的/META-INF/beans.xml。
2)还有另一个项目B使用项目A的拦截器。示例:
public class ProjectBClass {
…
@Transactional
public void interceptorMethod() {
…
}
…
}
所以我认为这个项目必须有一个启用拦截器的/META-INF/beans.xml。示例:
<beans>
<interceptors>
<class>br.com.company.projecta.TransactionalInterceptor</class>
</interceptors>
</beans>
3) 最后,有一个项目 C 使用项目 B 中的方法。示例:
public class ProjectCClass {
…
private ProjectBClass projectBClass;
…
public void testerMethod() {
…
this.projectBClass.interceptorMethod();
…
}
…
}
我不确定它是否必须有 /META-INF/beans.xml。
4)在同一个项目中,有一个测试该方法的集成测试。例子:
public class ProjectCClassTest {
…
@Test
public void test() {
ProjectCClass projectCClass = new ProjectCClass();
projectCClass.testerMethod();
…
Assert.assertEquals(…);
}
…
}
There are 3 projects that use CDI. Project A has an Interceptor for transaction control.
Project B uses Project A to save data in a database. When I run these unit tests, everything passes.
Project C uses Project B for integration tests. These tests fails when it finds the @AroundInvoke annotation from Interceptor.
What is going wrong? The interceptor is only in Project B beans.xml.
The exception stacktrace doesn't clear up my mind. It only show a jassist error. Debugging, I found that the problem comes from boostrap.deploybeans() inside Weld. So, I commented the @AroundInvoke in the interceptor class and everything goes fine with tests, but the insert on database. I think that happens because I removed the interceptor that creates transaction for inserts.
The code:
1) There is a project A which defines an annotation and an interceptor for this annotation. Example:
/Annotation/
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Transactional {
}
/Interceptor/
@Interceptor
@Transactional
public class TransactionalInterceptor implements Serializable {
…
@AroundInvoke
public Object intercept(InvocationContext context) throws Exception {
…
}
…
}
I think this project must have an empty /META-INF/beans.xml.
2) There is another project B that uses the interceptor from project A. Example:
public class ProjectBClass {
…
@Transactional
public void interceptorMethod() {
…
}
…
}
So I think this project must have a /META-INF/beans.xml that enables the interceptor. Example:
<beans>
<interceptors>
<class>br.com.company.projecta.TransactionalInterceptor</class>
</interceptors>
</beans>
3) Finally, there's a project C that uses the method from project B. Example:
public class ProjectCClass {
…
private ProjectBClass projectBClass;
…
public void testerMethod() {
…
this.projectBClass.interceptorMethod();
…
}
…
}
I am not sure if it must have a /META-INF/beans.xml.
4) In this same project, there is an integration test which tests the method. Example:
public class ProjectCClassTest {
…
@Test
public void test() {
ProjectCClass projectCClass = new ProjectCClass();
projectCClass.testerMethod();
…
Assert.assertEquals(…);
}
…
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
所有项目(打包为 .jar)中都需要
META-INF/beans.xml
您不应该自己实例化这些类。如果这样做,则它们不受 CDI 管理。让 CDI 实例化它们。例如看这里。
You need
META-INF/beans.xml
in all projects (packaged as .jar)You should not instantiate the classes yourself. If you do, they are not CDI managed. Let CDI instantiated them. For example look here.