是否需要在拦截器上定义一个拦截器绑定?

时间:2018-09-01 17:41:28

标签: java-ee ejb cdi

https://javaee.github.io/tutorial/cdi-adv-examples005.html#GKHPA的JEE8教程中,它具有一个拦截器,并带有自己的拦截器绑定。以下是本教程的摘录:

  

拦截器类LoggedInterceptor,及其拦截器绑定,   已记录,均在拦截器包中定义。记录的   拦截器绑定定义如下:

@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface Logged {
}
  

LoggedInterceptor类如下:

@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {    
    //...more code       
}

我的问题是,有必要在拦截器类本身上使用@Logged注释吗?我已经运行了没有@Logged注释的代码,即:

@Interceptor
public class LoggedInterceptor implements Serializable {
   //...

,它的行为似乎完全相同。通过玩弄代码,在我看来,将@Logged批注添加到方法foo中就是将foo标记为需要被拦截的方法的方式。那么将类LoggedInterceptor标记为@Logged的意义何在?

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

定义拦截器有两种方法,不要将它们混合在一起很重要。一种方法是使用@Interceptor和拦截器绑定,另一种方法(在EJB中更常用,并且在历史上更旧)与{{1}一起使用}。拦截器规范中对这两种方法都进行了详细说明,但让我简单介绍一下。

具有绑定(@Interceptors(Some.class) + @Interceptor

绑定是必需的,它才能正常工作,这是将拦截器与要拦截的类/方法“绑定”的东西。此外,需要通过@InterceptorBindingbeans.xml注释启用这些拦截器。启用会影响拦截器的顺序。

您需要具有拦截器绑定:

@Priority

然后使用绑定注释的拦截器本身(或更多)将其绑定到该绑定。

@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface SomeBinding {
}

最后,您现在可以将@SomeBinding @Interceptor @Priority(1) // I used this annotation to enable the interceptor instead of beans.xml public class MyInterceptor { @AroundInvoke public void someMethod(InvocationContext ctx) { ... ctx.proceed(); ... } } 应用于要拦截的方法和/或类。

@SomeBinding

无绑定(public class SomeClass { @SomeBinding public void doWhatYouDoBest() { // some logic } }

这些拦截器不需要绑定,要启用它们,您只需在{/ {1}}批注中列出拦截器类即可,该批注放在类/方法的顶部。将它们放入批注的顺序决定了它们被调用的顺序。

您也不需要在实际的拦截器类上放置@Interceptor

以下是通常应用这些拦截器的方式:

@Interceptors

拦截器可能看起来像这样:

@Interceptors

知道CDI支持这两种方式,但是我强烈建议坚持使用绑定方法,因为它是最新的且用途广泛,例如可以更好地处理层次结构和排序。

答案 1 :(得分:0)

不,您不可以,但是您必须在它拦截的类上声明拦截器,而不是使用注释

public class MyService {

    @Interceptors(LoggedInterceptor.class)
    public void myInterceptedMethod() {}

}

这有什么缺点?

  

您不能定义另一个拦截器,除非将其添加为“拦截器”列表的一部分

  

更改拦截器的实现要求您去找出所有旧拦截器的声明位置