如何告诉CDI容器"激活"一个豆?

时间:2017-09-03 18:06:05

标签: java java-ee ejb wildfly cdi

假设我有一些注射课程:

class MyBean {

    @Inject
    Helper helper;

    // all sorts of data
}

并且这个类是以CDI容器不知道它的方式创建的,如反射,序列化或new。在这种情况下,helpernull,因为CDI没有为我们初始化它。

有没有办法告诉CDI&#34;激活&#34;豆或至少注射?例如,好像它是用Instance<MyBean>#get创建的?

现在我有一个黑客,我做以下事情:

class SomeClass {

    @Inject
    Instance<MyBean> beanCreator;

    void activateBean() {
        MyBean mybean = ... // reflection/serialization/new
        MyBean realBean = beanCreator.get();
        Helper proxy = realBean.getHelper();
        mybean.setHelper(proxy);
        beanCreator.destroy(realBean);
    }
}

这看起来很糟糕,但它适用于我测试的所有内容。它只显示了我想要的最终结果。

如果重要的话,使用Wildfly 10.1。

1 个答案:

答案 0 :(得分:2)

首先,您使用MyBean的方式不是CDI方式;事实上,你操作所谓的非上下文对象。您正在做的是采用非CDI管理对象并要求CDI解决注入点。这是非常不寻常的,因为你处理生命周期的一部分(创建/破坏),同时要求CDI完成其余的工作。

在您的情况下,MyBean类需要成为InjectionTarget,这就是您应该开始寻找的方式。为了触发注射,你需要做这样的事情(在创建MyBean期间):

// Create an injection target from your given class
InjectionTarget<MyBean> it = beanManager.getInjectionTargetFactory(beanManager.createAnnotatedType(MyBean.class))
                .createInjectionTarget(null);
CreationalContext<MyBean> ctx = beanManager.createCreationalContext(null);
MyBean instance = new MyBean();
it.postConstruct(instance); // invoke @PostContruct
it.inject(instance, ctx); // trigger actual injection on the instance

请注意,这种方法通常很笨拙(因为难以使其工作和维护)并且最好将您的MyBean转换为真正的CDI bean并将整个生命周期管理留给CDI。但是,为此,您的问题并未提供足够的信息。