环境:Java EE 6
如果调用的bean是容器管理(CMT)还是bean管理(BMT),如何在Interceptor中确定?
答案 0 :(得分:2)
根据定义,Bean始终是容器管理的。
您可能想知道当前的交易CMT或BMT。因为@AroundInvoke拦截器方法在截获的业务方法的同一事务中执行,所以可以通过以下方式检查事务类型:
public class SomeInterceptor {
@Resource
private javax.ejb.SessionContext sessionContext;
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {
if (isCMT()) {
}
...
}
private boolean isCMT() {
try {
//throws IllegalStateException if not BMT
sessionContext.getUserTransaction();
return false;
}
catch (IllegalStateException ise) {
return true;
}
}
}
当然使用异常控制流程是不好的,但我不知道区分BMT和CMT的替代方法。
答案 1 :(得分:0)
您可以使用InvocationContext
获取调用拦截器的Class
和Method
。然后,您可以尝试解析它们的注释并确定事务管理类型。但是这种方法有一个很大的缺点:如果使用ejb-jar.xml
部署描述符设置事务管理属性,那么您根本找不到注释或无效的覆盖注释。您也可以尝试调用java.util.Map<java.lang.String,java.lang.Object> getContextData()
并发现结果。
答案 2 :(得分:0)
似乎在错误的级别解决问题。如果isCMT()
之类的测试无论如何都不是面向对象的。为什么不有两个拦截器,一个用于带有BMT的豆子,另一个用于CMT?对正确的bean使用正确的拦截器......如果需要,两个拦截器仍然可以通过继承公共父类来重用通用逻辑。