How can I tell the CDI container to “activate” a bean?

倖福魔咒の 提交于 2019-12-02 11:48:09

问题


Suppose I have some class with injections:

class MyBean {

    @Inject
    Helper helper;

    // all sorts of data
}

and this class was created in a way the CDI container is not aware of it like reflection, serialization or new. In this case the helper is null because the CDI did not initialize it for us.

Is there a way to tell CDI to "activate" the bean or at least its injection? e.g., as if it was created with Instance<MyBean>#get?

Right now I have a hack where I do the following:

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);
    }
}

This looks pretty bad but it works for everything I tested. It just shows what the end result is that I want.

Using Wildfly 10.1 if it matters.


回答1:


First of all, the way you use MyBean is not a CDI way; in fact you operate on so called non-contextual object. What you are doing is taking a non-CDI managed object and asking CDI to resolve injection points. This is quite unusual, as you handle part of the lifecycle (creation/destruction), while asking CDI to do the rest.

In your case, the MyBean class needs to become InjectionTarget, and that is the way you should start looking. In order to trigger injection you will want to do something like this (during creation of 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

Please note that this approach is usually clumsy (as in hard to make it work and maintain) and it might be better to instead turn your MyBean into a true CDI bean and leaving whole lifecycle management to CDI. For that, however, your question doesn't provide enough information.



来源:https://stackoverflow.com/questions/46026384/how-can-i-tell-the-cdi-container-to-activate-a-bean

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!