java @Inject 仅适用于 CDI 容器创建的 POJO?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12080317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 07:31:23  来源:igfitidea点击:

@Inject only working for POJOs created by CDI container?

javajakarta-eejava-ee-6cdi

提问by Sebi

I just want to confirm that I fully understood the prerequisites for CDI to work. If I have a class A:

我只想确认我完全理解 CDI 工作的先决条件。如果我有一个A类:

public class A {
    @Inject private B b;
}

Now when I instantiate this class using:

现在,当我使用以下方法实例化此类时:

A a = new A();

In that case, A.b will be null.

在这种情况下,Ab 将为空。

But if I define in another class a member:

但是如果我在另一个类中定义一个成员:

@Inject A a;

and later use a, a.b will be correctly populated?

后来使用a,ab会正确填充吗?

Does CDI only work if the class requiring an injection was also created by CDI container? Or what am I missing if injections turn out to be null while creating a POJO using ordinary instantiation with new (yes, I got beans.xml in place)?

仅当需要注入的类也是由 CDI 容器创建时,CDI 才有效吗?或者,如果在使用 new 的普通实例化创建 POJO 时注入结果为空,我会错过什么(是的,我有 beans.xml 到位)?

采纳答案by Adam Gent

While others have stated correctly that for the most part DI containers will not inject dependencies into bean that they did not instantiate this is not entirely true.

虽然其他人已经正确地指出,在大多数情况下,DI 容器不会将依赖项注入到它们没有实例化的 bean 中,但这并不完全正确。

Spring has a wonderful feature that will autowire the bean when you create it using new A(). You just have to use AspectJ and mark your bean with the @Configurableannotation.

Spring 有一个很棒的特性,当你使用new A(). 您只需要使用AspectJ 并用@Configurable注释标记您的 bean

@Configurable
public class A {
    @Inject private B b;
}

Its actually kind of an awesome feature cause you can do Active Record style POJO's while still honoring your DI (its in fact how Spring Roo does it).

它实际上是一种很棒的功能,因为您可以在执行 Active Record 样式的 POJO 的同时仍然尊重您的 DI(实际上 Spring Roo 就是这样做的)。

You should also know that with Spring you can autowire a bean programmatically after its been instantiated with the AutowireCapableBeanFactory. This is how it typically autowires JUnit Test Case Classes because JUnit creates the test case classes.

您还应该知道,使用 Spring,您可以在使用AutowireCapableBeanFactory实例化 bean 后以编程方式自动装配 bean 。这就是它通常自动装配 JUnit 测试用例类的方式,因为 JUnit 创建了测试用例类。

Yes Spring is not CDIbut in theory you could write your own @Configurablefor CDI or there is probably a CDI way of doing the above.

是的 Spring 不是 CDI,但理论上您可以@Configurable为 CDI编写自己的代码,或者可能有一种 CDI 方式来执行上述操作。

That being said the above is sort of a sophisticated feature (and kind of a hack) and as @JanGroth mentioned understaning the lifecycle bean management of the containeris critical whether its CDI, Spring, Guice etc.

话虽如此,上面是一种复杂的功能(和一种 hack),正如@JanGroth 所提到的,了解容器生命周期 bean 管理对于它的 CDI、Spring、Guice 等是否是至关重要的。

回答by jan groth

Does CDI only work if the class requiring an injection was also created by CDI container?

仅当需要注入的类也是由 CDI 容器创建时,CDI 才有效吗?

Yes, that's pretty much it. The lifecycle of a ManagedBeanis controlled by the container and should never be instantiated with the newkeyword (BTW: the same is true for EJBs & Spring beans). If you need to create a new ManagedBean you will probably want to use a producer method.

是的,差不多就是这样。a 的生命周期ManagedBean由容器控制,不应使用new关键字实例化(顺便说一句:EJB 和 Spring bean 也是如此)。如果您需要创建一个新的 ManagedBean,您可能需要使用生产者方法

回答by Adam Gent

You may use BeanProvider.injectFields(myObject);from Apache DeltaSpike.

您可以使用BeanProvider.injectFields(myObject);来自Apache DeltaSpike

回答by March

Yes, @Inject works only inside a container because it is done using interceptors on method calls. When the container creates a bean it wrappes it in interceptors which perform injection, and in the case of instantiation using newno interceptors will be called during bean method invocation, and there will be no injection.

是的,@Inject 只能在容器内工作,因为它是在方法调用上使用拦截器完成的。当容器创建一个 bean 时,它会将它包装在执行注入的拦截器中,并且在使用new实例化的情况下,在 bean 方法调用期间不会调用任何拦截器,也不会发生注入。

回答by Shivan Dragon

Here's the conditions needed for a class to be a managed bean (and hence, for the @Inject annotation to work on its fields/methods):

这是一个类成为托管 bean 所需的条件(因此,@Inject 注释在其字段/方法上工作):

http://docs.oracle.com/javaee/6/tutorial/doc/gjfzi.html

http://docs.oracle.com/javaee/6/tutorial/doc/gjfzi.html