拦截使用@Produces方法创建的CDI bean

Yev*_*nyL 3 interceptor cdi jakarta-ee

在我们的 JEE 应用程序中,我们创建了一个新注释@MyAnnotation,并将其设置在 CDI beans ( @ApplicationScoped ) 上。
然后我们有一个拦截器,它拦截所有带有@MyAnnotation注释的 bean 。
问题是它不适用于由@Produces方法创建的 bean。
这意味着拦截器没有被调用。

所以如果我们有这个类:

@ApplicationScoped
public class OtherClass
{
     @Inject
     private MyBean myBean;

     public void f()
     {
        myBean.g();
     }
}
Run Code Online (Sandbox Code Playgroud)

然后以下将起作用:

@ApplicationScoped
@MyAnnotation
public class MyBean
{
   public void g() {}
}
Run Code Online (Sandbox Code Playgroud)

但下面的不会:

@ApplicationScoped
public class MyBeanProducer 
{

    @Produces
    public MyBean create() 
    {
        return new MyBean();
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法让拦截器拦截使用 @Produces 创建的 CDI bean?

Yev*_*nyL 5

解决方案是使用InterceptionFactory (从CDI 2.0开始)来代理@Poduces方法生成的bean ,意思是:

@ApplicationScoped
public class MyBeanProducer 
{

    @Produces
    public MyBean create(InterceptionFactory<MyBean> interceptionFactory) 
    {
        return interceptionFactory.createInterceptedInstance(new MyBean());
    }
}
Run Code Online (Sandbox Code Playgroud)

@MyAnnotation应该位于MyBean上。
MyBean必须有一个无参数构造函数才能被代理,因为InterceptionFactory.createInterceptedInstance()正是这样做的 - 代理MyBean实例。我在这里
找到了解决方案