Jakarta ee 是否需要在拦截器上定义拦截器绑定?

Jakarta ee 是否需要在拦截器上定义拦截器绑定?,jakarta-ee,ejb,cdi,Jakarta Ee,Ejb,Cdi,在JEE8教程中,它有一个拦截器,它用自己的拦截器绑定进行了注释。以下内容摘自本教程: 拦截器类LoggedInterceptor及其拦截器绑定, 已记录,两者都在拦截器包中定义。记录的 拦截器绑定定义如下: LoggedInterceptor类如下所示: public class MyInterceptor1 { @AroundInvoke public void someMethod(InvocationContext ctx) { ... ctx.proceed()

在JEE8教程中,它有一个拦截器,它用自己的拦截器绑定进行了注释。以下内容摘自本教程:

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

LoggedInterceptor类如下所示:

public class MyInterceptor1 {
  @AroundInvoke
  public void someMethod(InvocationContext ctx) {
    ...
    ctx.proceed();
    ...
  }
}
我的问题是,有必要在拦截器类本身上使用@Logged注释吗?我在没有@Logged注释的情况下运行了代码,即:

@Interceptor
public class LoggedInterceptor implements Serializable {
   //...
它的行为方式似乎完全相同。在我看来,通过对代码进行处理,将@Logged注释添加到方法foo就是将foo标记为需要拦截的方法的方式。那么将LoggedInterceptor类标记为@Logged有什么意义呢


谢谢您的帮助。

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

public class MyService {

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

}
这有什么缺点

如果不将另一个拦截器添加为拦截器列表的一部分,则无法定义该拦截器

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


定义拦截器有两种方法,重要的是不要将它们混用在一起。一种是使用
@Interceptor
和拦截器绑定,另一种(更常用于EJB和历史上较早的版本)使用
@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
  }
}
没有绑定(
@Interceptors

这些拦截器不需要绑定,要启用它们,只需在类/方法顶部的
@interceptors
注释中列出拦截器类。将它们放入注释的顺序决定了调用它们的顺序

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

以下是您通常如何应用这些拦截器:

@Interceptors({MyInterceptor1.class, MyInterceptor2.class})
public void myMethod() {
 // do intercepted stuff
}
拦截器可能是这样的:

public class MyInterceptor1 {
  @AroundInvoke
  public void someMethod(InvocationContext ctx) {
    ...
    ctx.proceed();
    ...
  }
}
要知道CDI支持这两种方式,但我强烈建议使用绑定的方法,因为它更先进、更通用,例如可以更好地处理层次结构和排序

public class MyInterceptor1 {
  @AroundInvoke
  public void someMethod(InvocationContext ctx) {
    ...
    ctx.proceed();
    ...
  }
}