@Inject可以在pojo中使用

时间:2015-11-02 11:40:41

标签: java cdi java-ee-6

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

示例 Greeting.java

public Class Greeting {
 public String greet() {
   System.out.println("Hello");
 }
}

Test.java

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

   public void testGreet() {
    greeting.testGreet();
   }
}

当我调用testGreet()时,它会抛出NPE,为什么greeting实例为null。添加依赖项的@Inject方法是否仅用于容器托管bean? 注意:罐子不是问题。

3 个答案:

答案 0 :(得分:4)

TL; DR: @Inject-annotated字段仅填充容器实例化的bean。

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

  1. 调用bean的构造函数。
  2. @Inject-annotated fields(和其他一些 注释,@ PersistenceContext和@EJB例如) 填充。
  3. @ PostConstruct-annotated no-args方法被调用。
  4. 你的豆子已经完成了。
  5. 您正面临着一个经典的引导问题,即如何从非容器管理的代码转移到容器管理的代码中。您的选择是:

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

答案 1 :(得分:0)

您需要一个JavaEE容器,而不是需要将Greeting和Test定义为托管bean。之后你可以互相注入。

试着看看: https://docs.oracle.com/javaee/6/tutorial/doc/girch.html

答案 2 :(得分:0)

您的类应从Serializable实现,以便可以作为“ CDI Bean”注入