Java 我如何告诉CDI容器;激活";豆子?

Java 我如何告诉CDI容器;激活";豆子?,java,jakarta-ee,ejb,wildfly,cdi,Java,Jakarta Ee,Ejb,Wildfly,Cdi,假设我有一些关于注射的课程: class MyBean { @Inject Helper helper; // all sorts of data } 这个类是以CDI容器不知道的方式创建的,比如反射、序列化或new。在这种情况下,helper是null,因为CDI没有为我们初始化它 有没有办法告诉CDI“激活”bean或至少激活它的注入?e、 例如,就好像它是用实例#get创建的一样 现在我有一个黑客,我做了以下几点: class SomeClass {

假设我有一些关于注射的课程:

class MyBean {

    @Inject
    Helper helper;

    // all sorts of data
}
这个类是以CDI容器不知道的方式创建的,比如反射、序列化或
new
。在这种情况下,
helper
null
,因为CDI没有为我们初始化它

有没有办法告诉CDI“激活”bean或至少激活它的注入?e、 例如,就好像它是用
实例#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);
    }
}
class-SomeClass{
@注入
实例beanCreator;
void activateBean(){
MyBean MyBean=…//反射/序列化/新建
MyBean realBean=beanCreator.get();
Helper proxy=realBean.getHelper();
setHelper(代理);
销毁(realBean);
}
}
这看起来很糟糕,但它适用于我测试的所有东西。它只是显示了我想要的最终结果


如果有必要,可以使用Wildfly 10.1。

首先,您使用MyBean的方式不是CDI方式;事实上,您操作的是所谓的非上下文对象。您要做的是获取一个非CDI管理的对象,并要求CDI解析注入点。这是非常不寻常的,因为您处理生命周期的一部分(创建/销毁),而要求CDI完成其余的工作

在您的例子中,
MyBean
类需要变成,这就是您应该开始寻找的方式。为了触发注入,您需要执行如下操作(在创建
MyBean
期间):

//从给定类创建注入目标
InjectionTarget it=beanManager.getInjectionTargetFactory(beanManager.createAnnotatedType(MyBean.class))
.createInjectionTarget(空);
CreationContext ctx=beanManager.CreateCreationContext(null);
MyBean实例=新的MyBean();
it.postConstruct(实例);//调用@postcontract
it.inject(实例,ctx);//在实例上触发实际注入

请注意,这种方法通常很笨拙(因为很难让它工作和维护),相反,最好将您的
MyBean
转变为真正的cdibean,并将整个生命周期管理留给CDI。但是,您的问题并没有提供足够的信息。

谢谢。上下文:
MyBean
是我需要保存和加载的状态对象的一部分,当前正在进行序列化(请参阅我的上一篇文章)。我读到在实体中使用注入不是一个好主意,但这个实体需要它。另外,在编写
newmybean()
的地方,可以用反序列化或反射来代替它,对吗?也许你应该考虑一下,如果使用Helper赋予MyBean它所履行的职责是合理和必要的。有时,如果让一些
装饰器
适配器
甚至是
迭代器
处理这个问题,结构会更好。这些bean通常是容器创建的正常范围的bean,并且能够与您的数据对象一起工作。如果您提供用例,说明实体实际上如何依赖于这些bean,那么我们可以帮助将其重构为更好的设计,而不需要注入实体。理想情况下,您应该将实体视为数据,并使用单独的bean来处理它data@Mark是的,我认为您可以使用反序列化。在我的示例中,该行的目的是获取对实际实例的引用。所以它应该可以工作。Iv'e测试了这个,bean的注入是
null
,所以它不能正常工作:(
// 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