1

环境:Java EE 6

如何在拦截器中确定调用的 bean 是容器管理 (CMT) 还是 bean 管理 (BMT)?

4

3 回答 3

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 的替代方法。

于 2012-08-14T09:56:33.497 回答
0

您可以使用InvocationContext获取ClassMethod调用拦截器的对象。然后您可以尝试为它们解析注释并确定事务管理类型。但是这种方法有一个巨大的缺点:如果事务管理属性是使用ejb-jar.xml部署描述符设置的,那么您根本找不到任何注释或无效的覆盖注释。您也可以尝试调用java.util.Map<java.lang.String,java.lang.Object> getContextData()和发现结果。

于 2012-08-14T09:42:03.100 回答
0

似乎在错误的层面上解决了问题。如果像这样isCMT()的测试无论如何都不是非常面向对象的。为什么不使用两个拦截器,一个用于带有 BMT 的 bean,另一个用于 CMT?为正确的 bean 使用正确的拦截器......如果需要,两个拦截器仍然可以通过继承一个公共父类来重用公共逻辑。

于 2012-08-14T12:40:20.313 回答