7.11. インターセプター
インターセプターを使用すると、Bean のメソッドを直接変更せずに Bean のビジネスメソッドに機能を追加できます。インターセプターは、Bean のビジネスメソッドの前に実行されます。インターセプターは、Jakarta Enterprise Beans 仕様の一部として定義されています。
Contexts and Dependency Injection を使用すると、インターセプターと Bean をバインドするためにアノテーションを使用できます。
インターセプションポイント
- ビジネスメソッドインターセプション: ビジネスメソッドのインターセプターは、Bean のクライアントによる Bean のメソッド呼び出しに適用されます。
- ライフサイクルコールバックインターセプション: ライフサイクルコールバックインターセプションは、コンテナーによるライフサイクルコールバックの呼び出しに適用されます。
- タイムアウトメソッドインターセプター: タイムアウトメソッドインターセプターは、コンテナーによる Enterprise Java Bean タイムアウトメソッドの呼び出しに適用されます。
インターセプターの有効化
デフォルトでは、すべてのインターセプターが無効になります。インターセプターは、Bean アーカイブの beans.xml
記述子を使用して有効にすることができます。ただし、このアクティベーションは、そのアーカイブの Bean に対してのみ適用されます。CDI 1.1 以降、インターセプターは、@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>
<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
ファイルによって呼び出されると、移植不可能な動作を引き起こします。したがって、複数の Contexts and Dependency Injection 実装全体で整合性のある動作を維持するには、この組み合わせで有効にしないでください。
7.11.1. Contexts and Dependency Injection におけるインターセプターの使用
Contexts and Dependency Injection を使用すると、インターセプターコードを単純化し、ビジネスコードに適用しやすくなります。
Contexts and Dependency Injection を使用しない場合は、インターセプターに以下の 2 つの問題が浮上します。
- Bean は、インターセプター実装を直接指定する必要があります。
- アプリケーションの各 Bean は、インターセプターの完全なセットを適切な順序で指定する必要があります。この場合、アプリケーション全体でインターセプターを追加または削除するには時間がかかり、エラーが発生する傾向があります。
Contexts and Dependency Injection におけるインターセプターの使用
インターセプターバインディングタイプを定義します。
Copy to Clipboard Copied! Toggle word wrap Toggle overflow @InterceptorBinding @Retention(RUNTIME) @Target({TYPE, METHOD}) public @interface Secure {}
@InterceptorBinding @Retention(RUNTIME) @Target({TYPE, METHOD}) public @interface Secure {}
インターセプター実装をマーク付けします。
Copy to Clipboard Copied! Toggle word wrap Toggle overflow @Secure @Interceptor public class SecurityInterceptor { @AroundInvoke public Object aroundInvoke(InvocationContext ctx) throws Exception { // enforce security ... return ctx.proceed(); } }
@Secure @Interceptor public class SecurityInterceptor { @AroundInvoke public Object aroundInvoke(InvocationContext ctx) throws Exception { // enforce security ... return ctx.proceed(); } }
開発環境でインターセプターを使用します。
Copy to Clipboard Copied! Toggle word wrap Toggle overflow @Secure public class AccountManager { public boolean transfer(Account a, Account b) { ... } }
@Secure public class AccountManager { public boolean transfer(Account a, Account b) { ... } }
META-INF/beans.xml
またはWEB-INF/beans.xml
ファイルに追加して、デプロイメントでインターセプターを有効にします。Copy to Clipboard Copied! Toggle word wrap Toggle overflow <beans> <interceptors> <class>com.acme.SecurityInterceptor</class> <class>com.acme.TransactionInterceptor</class> </interceptors> </beans>
<beans> <interceptors> <class>com.acme.SecurityInterceptor</class> <class>com.acme.TransactionInterceptor</class> </interceptors> </beans>
インターセプターは、リストされた順序で適用されます。