5

设想

在 2 种方法上的相同 EJB 中的 2x 相同拦截器:

...
 @Interceptors(PerformanceAuditor.class)
public Date refreshIfNecessary() {
    // there is also the PerformanceAuditor-Interceptor on this method
    Pair<Date,String> lastImportDate = importDbDAO.findLatestImportLog();

    someContainer.reloadIfNecessary(lastImportDate);
    return lastImportDate.getLeft();
}

@Interceptors(PerformanceAuditor.class)
public boolean checkAndRefreshIfNecessary(final Date importDate) {
    Date lastImportDate = refreshIfNecessary();
    return lastImportDate.after(importDate);
}
...

现在我们在外部调用这个 EJB 的方法,结果如下:

  • 调用refreshIfNecessary() -> PerformanceAuditor 被调用2 次
  • 调用checkAndRefreshIfNecessary() -> PerformanceAuditor 也被调用了2 次!(但预计 3 次,因为多了一层嵌套!)

那么这里发生了什么?

4

1 回答 1

10

答案很简单:

只有当作为“EJB 调用”(即通过它们的 EJB 接口)调用时,拦截器才会“触发”。但是在checkAndRefreshIfNecessary() 中,对 checkAndRefreshIfNecessary()调用是一个简单的 Java 方法调用,因此不会被容器注意到。

解决方案:要在内部调用 EJB 中的方法作为 EJB 调用,您必须通过它的接口进行访问,例如通过注入的 SessionContext 然后通过 context.getEJBLocalObject() ... 但这当然不是一个很好的解决方案!在这种情况下,最好重新考虑您的设计!

PS:这是一个很好的例子,人们仍然需要了解应用服务器的内部结构。不幸的是,从 EJB3 开始,大多数功能都非常易于使用,以至于越来越多的开发人员不会遇到内部问题,这会更频繁地导致此类错误或至少是糟糕的设计......

于 2013-02-11T10:02:42.260 回答