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

Seb*_*ebi 9 java java-ee cdi java-ee-6

我只想确认我完全理解CDI工作的先决条件.如果我有A班:

public class A {
    @Inject private B b;
}
Run Code Online (Sandbox Code Playgroud)

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

A a = new A();
Run Code Online (Sandbox Code Playgroud)

在这种情况下,Ab将为null.

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

@Inject A a;
Run Code Online (Sandbox Code Playgroud)

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

CDI仅在需要注射的类也由CDI容器创建时才起作用吗?或者,如果使用普通的实例化创建一个POJO时,如果注射结果为null,我会错过什么(是的,我得到了beans.xml)?

jan*_*oth 9

CDI仅在需要注射的类也由CDI容器创建时才起作用吗?

是的,这就是它.a的生命周期ManagedBean由容器控制,永远不应该用new关键字实例化(BTW:EJB和Spring bean也是如此).如果需要创建新的ManagedBean,则可能需要使用producer方法.

  • @AdamGreen - 根据我的理解,OP完全没有意识到容器接管了bean生命周期的责任.这就是为什么我仍然认为`new Foo()`不适合用于依赖注入的hello world尝试 - 即使大多数容器(包括CDI)都提供了解决此限制的方法. (2认同)

Ada*_*ent 4

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

Spring 有一个很棒的功能,当您使用创建 bean 时,它会自动装配 bean new A()。您只需使用AspectJ 并用注释标记您的 bean@Configurable即可。

@Configurable
public class A {
    @Inject private B b;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

话虽这么说,上面是一种复杂的功能(也是一种 hack),正如 @JanGroth 提到的,了解容器的生命周期 bean 管理至关重要,无论是 CDI、Spring、Guice 等。

  • 嗯,OP 询问了 CDI,最终接受的答案描述了 Spring 功能。很奇怪。:) (6认同)
  • @jangroth 我不认为我会被标记为正确。我只是把我的答案写出来,以防有人想用 `new *()` 做 DI ...我也有点猜测他真的想要那样,但也许我只是让他更加困惑。你总是可以-1我的帖子:) (2认同)