【问题标题】:Is it necessary to define an interceptor binding on an interceptor?是否需要在拦截器上定义拦截器绑定?
【发布时间】:2018-09-01 17:41:28
【问题描述】:

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 有什么意义呢?

感谢您的帮助。

【问题讨论】:

    标签: jakarta-ee ejb cdi


    【解决方案1】:

    定义拦截器有两种方法,重要的是不要将它们混合在一起。一种是使用@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 支持这两种方式,但我强烈建议坚持使用绑定的方法,因为它更加最新且用途广泛,例如可以更好地处理层次结构和排序。

    【讨论】:

      【解决方案2】:

      不,你没有,但是你必须在它拦截的类上声明拦截器,而不是使用注释,即

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

      这样做有什么缺点?

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

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

      【讨论】:

        猜你喜欢
        • 2012-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-22
        • 2017-09-26
        • 1970-01-01
        • 2014-03-10
        相关资源
        最近更新 更多