インターセプタ
EJB3と同じく、Web Beansではjavax.interceptorパッケージを用いてメソッドインターセプタを作成することができる。EJB3との違いは、@Interceptorsアノテーションではなく、メタアノテーションの仕組みを使用してインターセプタをコンポーネントに関連付けるのが可能な点だ。
たとえば、リスト23のようなインターセプタがあったとする。
リスト23
@Interceptor
public class LogInterceptor {
@AroundInvoke
public void aroundInvoke(InvocationContext ic) {
...
}
}
これをクラスに関連付けるには、通常、@Interceptorsアノテーションを使用する。
リスト24
@Component
@Interceptors({LogInterceptor.class})
public class GreetingPrinter {
...
}
Web Beansの提供する枠組みを使用すると、アノテーションを用いてインターセプタのバインドを行うことが可能だ。そのためには、まず@IntercepterBindingTypeを付与したアノテーションを作成する。
リスト25
@InterceptorBindingType
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface Log {
}
このアノテーションを、インターセプタにも付与する。これで、インターセプタとアノテーションが関連付けられる。
リスト26
<strong>@Log</strong>
@Interceptor
public class LogInterceptor {
@AroundInvoke
public void aroundInvoke(InvocationContext ic) {
...
}
}
そして、コンポーネントにインターセプタを関連付けるには、作成したアノテーションを付与するだけだ。
リスト27
@Component
@Log
public class GreetingPrinter {
...
}
また、メソッドを限定してインターセプタを適用することも可能だ。
リスト28
@Component
public class GreetingPrinter {
@Log
public void print() {
...
}
}
最後に重要なことは、こうして作成したインターセプタはデフォルトでは有効にならないと言うことだ。これらを有効にするには、web-beans.xmlにてインターセプタのクラス名を指定する。
リスト29
<interceptors>
<interceptor>examples.Log</interceptor>
<interceptor>examples.Transactional</interceptor>
</intercepters>
<intercepters>内には複数のインターセプタを定義できるが、その順序が重要だ。インターセプタの適用順序は、ここに記述した順序に従う。