java - 如何使用 CDI 注入(inject)到 3rd 方实例化的对象中

标签 java dependency-injection cdi weld

我有一个由第 3 方代码实例化的类(它使用反射来创建对象。)我提供了他们接口(interface)的实现,他们创建了对象。在我的实现中,我想使用 CDI 来注入(inject)执行逻辑的服务。执行此操作的正确方法是什么?

public interface ThirdPartyInterface {
    public void DoSomething();
}

public class InjectedService {
    public void DoSomeLogic() { ... }
}

public class MyImplementation implements ThirdPartyInterface {
    @Inject InjectedService service;

    @Override
    public void DoSomething() {
        service.DoSomeLogic();
    }
}

我最初认为这可以通过 CDI 的魔力来实现,但发现我的服务对象为空。

到目前为止我唯一想到的就是在构造函数中手动注入(inject)服务

 public MyImplementation() {
     CDI<Object> cdi = CDI.current();
     service = cdi.select(InjectedService.class).get();
 }

这是获取实例的正确/唯一/最佳方式吗?我正在使用 Weld 进行 CDI 实现。

我还发现这在构造函数中有效:

    public MyImplementation() {
        CDI<Object> cdi = CDI.current();
        BeanManager bm = cdi.getBeanManager();
        AnnotatedType<MyImplementation> myType = bm.createAnnotatedType(MyImplementation.class);
        Set<Bean<?>> beans = bm.getBeans(MyImplementation.class);
        Bean<?> bean = bm.resolve(beans);
        @SuppressWarnings("unchecked")
        CreationalContext<MyImplementation> cc = (CreationalContext<MyImplementation>)bm.createCreationalContext(bean);
        bm.createInjectionTarget(myType).inject(this, cc);
   }

最佳答案

只要有人手动创建对象,默认情况下,CDI 就不会向其中注入(inject)任何内容。

您使用构造函数注入(inject)的方法可能会奏效,除非您进入 EAR 等 CDI.current() 可能无法达到您的预期。

有一种方法可以让 CDI 注入(inject)到手动创建的对象中——第 3 方必须执行此步骤才能使其工作。您需要 BeanManager 和一个要注入(inject)的实例:

        BeanManager beanManager = ...; // get hold of bean manager, can be injected
        CreationalContext<Object> ctx = beanManager.createCreationalContext(null);
        @SuppressWarnings("unchecked")
        InjectionTarget<MyImplementation> injectionTarget = (InjectionTarget<MyImplementation>) beanManager
            .getInjectionTargetFactory(beanManager.createAnnotatedType(myImplementationInstance.getClass())).createInjectionTarget(null);
        injectionTarget.inject(myImplementationInstance, ctx);

注意 - 执行此操作后,您有责任在不再需要对象后对其进行清理。将 CreationContext 存储在某处并对其调用 release() 方法以便正确处理它(包括所有可能的销毁前调用等)。/p>

或者,既然您已经在使用 CDI,为什么第 3 方不简单地 @Inject 您提供的 bean?

关于java - 如何使用 CDI 注入(inject)到 3rd 方实例化的对象中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52613022/

相关文章:

java - 为 Eclipse 安装了 Hibernate Tools 插件,但无法访问代码生成功能

java - 如何将托管bean(非静态)注入(inject)静态方法?

c# - 通过构造函数依赖注入(inject)打破循环依赖

java - 有没有办法重新注入(inject)/更新注入(inject)的 bean 字段?

java - 从类路径访问资源文件

java - 无法使用 Intent 调用其他 Activity

java - 安卓公钥加密

java - 一种允许单个 Java 代码库覆盖许多不同版本的方法?

java - CDI 拦截器和事务传播

mysql - Hibernate 不关闭 MySql 连接