7.11. インターセプター

インターセプターを使用すると、Bean のメソッドを直接変更せずに Bean のビジネスメソッドに機能を追加できます。インターセプターは、Bean のビジネスメソッドの前に実行されます。インターセプターは、Jakarta Enterprise Beans 仕様の一部として定義されています。

Jakarta Contexts and Dependency Injection を使用すると、インターセプターと Bean をバインドするためにアノテーションを使用できます。

インターセプションポイント

  • ビジネスメソッドインターセプション: ビジネスメソッドのインターセプターは、Bean のクライアントによる Bean のメソッド呼び出しに適用されます。
  • ライフサイクルコールバックインターセプション: ライフサイクルコールバックインターセプションは、コンテナーによるライフサイクルコールバックの呼び出しに適用されます。
  • タイムアウトメソッドインターセプト: タイムアウトメソッドインターセプターは、コンテナーによる Jakarta Enterprise Beans タイムアウトメソッドの呼び出しに適用されます。

インターセプターの有効化

デフォルトでは、すべてのインターセプターが無効になります。インターセプターは、Bean アーカイブの beans.xml 記述子を使用して有効にすることができます。ただし、このアクティベーションは、そのアーカイブの Bean に対してのみ適用されます。

@Priority アノテーションを使用して、アプリケーション全体のインターセプターを有効にできます。

例: beans.xml のインターセプターの有効化

<beans
   xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://xmlns.jcp.org/xml/ns/javaee
      http://xmlns.jcp.org/xml/ns/javaee/beans_2.0.xsd">
   <interceptors>
      <class>org.mycompany.myapp.TransactionInterceptor</class>
   </interceptors>
</beans>

XML 宣言を使用すると、以下の 2 つのことが可能になります。

  • システムでインターセプターの順序を指定して、結果が正確になるようにすることができます。
  • デプロイメント時にインターセプタークラスを有効または無効にすることができます。

@Priority を使用して有効にされたインターセプターは、beans.xml ファイルを使用して有効にされたインターセプターよりも前に呼び出されます。

注記

インターセプターが @Priority によって有効になり、同時に beans.xml ファイルによって呼び出されると、移植不可能な動作を引き起こします。したがって、複数の Jakarta Contexts and Dependency Injection 実装全体で整合性のある動作を維持するには、この組み合わせで有効にしないでください。

7.11.1. Jakarta Contexts and Dependency Injection とインターセプターの使用

Jakarta Contexts and Dependency Injection を使用すると、インターセプターコードを単純化し、ビジネスコードに適用しやすくなります。

Jakarta Contexts and Dependency Injection がない場合、インターセプターには次の 2 つの問題があります。

  • Bean は、インターセプター実装を直接指定する必要があります。
  • アプリケーションの各 Bean は、インターセプターの完全なセットを適切な順序で指定する必要があります。この場合、アプリケーション全体でインターセプターを追加または削除するには時間がかかり、エラーが発生する傾向があります。
Jakarta Contexts and Dependency Injection でのインターセプターの使用
  1. インターセプターバインディングタイプを定義します。

    @InterceptorBinding
    @Retention(RUNTIME)
    @Target({TYPE, METHOD})
    public @interface Secure {}
  2. インターセプター実装をマーク付けします。

    @Secure
    @Interceptor
    public class SecurityInterceptor {
      @AroundInvoke
      public Object aroundInvoke(InvocationContext ctx) throws Exception {
        // enforce security ...
        return ctx.proceed();
        }
    }
  3. 開発環境でインターセプターを使用します。

    @Secure
    public class AccountManager {
      public boolean transfer(Account a, Account b) {
        ...
      }
    }
  4. META-INF/beans.xml または WEB-INF/beans.xml ファイルに追加して、デプロイメントでインターセプターを有効にします。

    <beans>
      <interceptors>
        <class>com.acme.SecurityInterceptor</class>
        <class>com.acme.TransactionInterceptor</class>
      </interceptors>
    </beans>

インターセプターは、リストされた順序で適用されます。