在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的意义何在?
感谢您的帮助。
答案 0 :(得分:3)
定义拦截器有两种方法,不要将它们混合在一起很重要。一种方法是使用@Interceptor
和拦截器绑定,另一种方法(在EJB中更常用,并且在历史上更旧)与{{1}一起使用}。拦截器规范中对这两种方法都进行了详细说明,但让我简单介绍一下。
具有绑定(@Interceptors(Some.class)
+ @Interceptor
)
绑定是必需的,它才能正常工作,这是将拦截器与要拦截的类/方法“绑定”的东西。此外,需要通过@InterceptorBinding
或beans.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() {}
}
这有什么缺点?
您不能定义另一个拦截器,除非将其添加为“拦截器”列表的一部分
和
更改拦截器的实现要求您去找出所有旧拦截器的声明位置