如何在CDI中拦截Conversation的begin与end方法?
问题解答
原方案的问题
你的核心思路(用CDI可移植扩展动态绑定拦截器)是合理的,但选错了CDI扩展的事件类型:
ProcessAnnotatedType事件仅针对CDI通过类扫描发现的自定义Bean(比如带@Named、@RequestScoped等注解的类),而Conversation是容器内置的系统Bean,不会触发这个事件,所以你的判断条件永远不会成立。
可行实现方式
你需要改用ProcessBean事件来处理内置Bean,具体步骤如下:
- 修改CDI扩展类,监听
ProcessBean<Conversation>事件:
public class ConversationInterceptorExtension implements Extension { void processConversationBean(@Observes ProcessBean<Conversation> event) { // 获取Bean配置器,绑定拦截器注解 event.configureBean().interceptors(MyInterceptorBinding.class); } }
- 确保你的拦截器绑定注解是标准定义的:
@InterceptorBinding @Target({TYPE, METHOD}) @Retention(RUNTIME) public @interface MyInterceptorBinding { }
- 实现拦截器类,处理目标方法的调用:
@Interceptor @MyInterceptorBinding public class ConversationInterceptor { @AroundInvoke public Object interceptConversationMethods(InvocationContext ctx) throws Exception { String methodName = ctx.getMethod().getName(); if ("begin".equals(methodName) || "end".equals(methodName)) { // 这里添加你的拦截逻辑,比如日志记录、参数校验等 System.out.println("拦截到Conversation方法调用:" + methodName); } return ctx.proceed(); } }
- 在
beans.xml中注册拦截器(CDI 1.1+也可使用@Priority注解替代):
<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" version="2.0"> <interceptors> <class>com.yourpackage.ConversationInterceptor</class> </interceptors> </beans>
额外注意点
- 部分CDI容器(如WildFly)对内置Bean的拦截有版本限制,测试时需确认容器是否支持对
Conversation这类系统Bean的拦截操作。 - 若仅需拦截特定方法,可在拦截器中通过
InvocationContext精准判断方法名,或在拦截器绑定中配置更细致的方法匹配规则。
内容的提问来源于stack exchange,提问作者Leonardo Scommegna
相关产品推荐
相关产品推荐

