可以在pojo中使用@Inject

San*_*and 3 java cdi java-ee-6

我正在尝试使用和理解CDI,当我在简单的pojo类中使用@Inject时,它会抛出NPE。

示例Greeting.java

public Class Greeting {
 public String greet() {
   System.out.println("Hello");
 }
}
Run Code Online (Sandbox Code Playgroud)

Test.java

 import javax.inject.Inject;
 public class Test {
   @Inject 
   private Greeting greeting;

   public void testGreet() {
    greeting.testGreet();
   }
}
Run Code Online (Sandbox Code Playgroud)

当我调用testGreet()时,它抛出NPE,为什么问候实例为null。@Inject添加依赖项的方式仅在容器管理的Bean中使用吗?注意:这里不是jar的问题。

小智 6

TL; DR:@Inject注释的字段仅用于容器实例化的Bean。

加长版:CDI容器为您提供了许多实用程序,可以轻松地将依赖项注入到bean中,但是魔术无法正常工作。如果客户端Bean本身是由容器实例化的,则容器只能填充客户端Bean的带注释字段。当容器实例化对象时,事件序列如下:

  1. 您的bean的构造函数被调用。
  2. 填充@Inject注释的字段(以及其他一些注释,例如@PersistenceContext和@EJB)。
  3. 调用@PostConstruct注释的no-args方法。
  4. 你的豆子吃完了。

您面临一个经典的引导问题,即如何从非容器管理的代码转换为容器管理的代码。您的选择是:

  1. 通过JNDI查找从JavaEE容器访问BeanManager实例。这是技术性的,有点笨拙。
  2. 使用CDI扩展库,例如Apache DeltaSpike。(实施例:BeanProvider.getContextualReference(Test.class, false);
  3. 修改您的应用程序以在可以注入Test类而不是调用的情况下启动new Test();。例如,可以通过设置启动单例ejb来完成此操作,该单例在@PostConstruct注释的初始化中调用您的测试。

希望这可以帮助。