9

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

public class A {
    @Inject private B b;
}

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

A a = new A();

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

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

@Inject A a;

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

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

4

5 回答 5

10

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

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

于 2012-08-22T19:49:54.953 回答
4

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

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

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

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

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

是的 Spring 不是 CDI,但理论上你可以为 CDI 编写自己的@Configurable,或者可能有一种 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 container is critical whether its CDI, Spring, Guice etc.

于 2012-08-22T20:12:26.503 回答
2

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

于 2017-08-02T06:43:13.343 回答
1

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

于 2012-08-22T19:50:14.963 回答
0

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

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

于 2012-08-22T19:49:28.150 回答