5

シナリオ

2 つのメソッドの同じ EJB 内の 2 つの同じインターセプター:

...
 @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 回呼び出されます。(ただし、ネスト レベルが 1 つ増えるため、3 回と予想されます!)

ここで何が起こっているのでしょうか?

4

1 に答える 1

10

答えは簡単です。

インターセプターは、"EJB 呼び出し" として (つまり、EJB インターフェースを介して) 呼び出された場合にのみ "トリガー" します。しかし、checkAndRefreshIfNecessary() では、checkAndRefreshIfNecessary()呼び出しは単純な Java メソッドの呼び出しであるため、コンテナーは認識しません。

解決策: EJB 内のメソッドを EJB 呼び出しとして内部的に呼び出すには、そのインターフェースを介してアクセスする必要があります。たとえば、注入された SessionContext を介して、次に context.getEJBLocalObject()を介してアクセスできます... しかし、これは確かにきれいな解決策ではありません! そのような場合は、設計を再考することをお勧めします。

PS:これは、アプリケーション サーバーの内部を理解する必要がある素晴らしい例です。残念なことに、EJB3 以降では、ほとんどの機能が非常に使いやすいため、そのようなエラーや少なくとも悪い設計につながる可能性が高くなる内部構造に直面する開発者がますます増えなくなります...

于 2013-02-11T10:02:42.260 に答える