7.11. 拦截器
拦截器允许您在 Bean 的业务方法中添加功能,而无需直接修改 bean 的方法。拦截器在 Bean 的任何业务方法之前执行。拦截器定义为 Jakarta Enterprise Beans 规范的一部分。
通过允许您使用注解将拦截器绑定到 bean,上下文和依赖注入功能增强了此功能。
拦截点
- 业务方法拦截器:商业方法拦截器适用于 Bean 的客户调用 Bean 方法。
- 生命周期回调拦截器:生命周期回调拦截器适用于容器调用的生命周期回调。
- 超时方法拦截器:超时方法拦截器应用于容器调用企业 Java Bean 超时方法。
启用 Interceptors
默认情况下,禁用所有拦截器。您可以使用 bean 存档的 beans.xml
描述符启用拦截器。但是,此激活仅适用于该存档中的 bean。从 CDI 1.1 开始,可以使用 @Priority
注释为整个应用启用拦截器。
示例:在 beans.xml
中启用 Interceptors
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2.0.xsd"> <interceptors> <class>org.mycompany.myapp.TransactionInterceptor</class> </interceptors> </beans>
使 XML 声明解决了两个问题:
- 它可让您在系统中指定拦截器的排序,以确保确定行为。
- 它可让您在部署时启用或禁用拦截器类。
在使用 beans.xml
文件启用拦截器之前,使用 @Priority
启用的拦截器会被调用。
由 @Priority
启用拦截器并且同时被 beans.xml
文件调用会导致无法移植的行为。因此,应避免这种启用组合,以便在不同的上下文和依赖注入实施之间保持一致的行为。
7.11.1. 将 Interceptors 与上下文和依赖注入一起使用
上下文和依赖注入可简化拦截器代码,更轻松地应用于您的业务代码。
如果没有上下文和依赖注入,拦截器有两个问题:
- Bean 必须直接指定拦截器实施。
- 应用程序中的每个 bean 都必须以正确的顺序指定完整的拦截器集合。这使得在应用程序范围内添加或移除拦截器会非常耗时且容易出错。
将 Interceptors 与上下文和依赖注入一起使用
定义拦截器绑定类型。
@InterceptorBinding @Retention(RUNTIME) @Target({TYPE, METHOD}) public @interface Secure {}
标记拦截器实施。
@Secure @Interceptor public class SecurityInterceptor { @AroundInvoke public Object aroundInvoke(InvocationContext ctx) throws Exception { // enforce security ... return ctx.proceed(); } }
在您的开发环境中使用拦截器。
@Secure public class AccountManager { public boolean transfer(Account a, Account b) { ... } }
通过将其添加到
META-INF/beans.xml 或
文件,在部署中启用拦截器。WEB-INF/beans.xml
<beans> <interceptors> <class>com.acme.SecurityInterceptor</class> <class>com.acme.TransactionInterceptor</class> </interceptors> </beans>
拦截器按照列出的顺序应用。