Singleton CDI @Inject空指针异常

时间:2017-04-03 08:45:13

标签: java nullpointerexception singleton cdi inject

我需要使用依赖注入从某些ejb(Stateless和Singleton)触发事件。我不使用Spring,Guice等。 问题是当我通过getInstance()调用它的方法时,我在其中一个bean中得到了NPE。以下是代码段:

@Stateless
@LocalBean
public class ControllerStartStop {
    @Inject
    private Event<SomeWebMessage> webEvent; 

    public String startCircle(String passwordP, String passwordH) {
    .........
    String res = "some msg";
    webEvent.fire(new SomeWebMessage(res, 0));   // this works fine
    MainDay.getInstance().startDay();      // NullPointerException

这是MainDay单身人士:

@Singleton
public class MainDay {
    private static final MainDay mDay = new MainDay();
    public static MainDay getInstance() {   return mDay ;   }

    @Inject
    private Event<SomeWebMessage> webEvent; 

    public void startDay() {
        String s = new String("MainDay");
        webEvent.fire(new SomeWebMessage(s,0));   // NullPointerException

beans.xml位于META-INF:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                           http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       version="1.1" bean-discovery-mode="all">

</beans>

当我从MainDay.initDS()等静态方法的调用中触发事件或者Sheduler调用方法startDay()时,没有NPE( @Schedule(hour =“”, minute =“”,second =“ / 10”)*。 我不知道是什么原因

2 个答案:

答案 0 :(得分:0)

请注意,@Singleton表示容器(EJB或CDI,取决于它是哪个注释)将管理实例,即不应自己创建它。< / p>

如果您通过private static final MainDay mDay = new MainDay();创建实例,则不会被容器注入,因此webEvent将为空。除此之外,容器不知道该实例,并且在其他地方使用@Inject MainDay很可能会产生另一个实例。

因此,只需直接使用注入(或查找,如果需要):

class ControllerStartStop  {
  @Inject
  private MainDay mDay;

  ...
  public String startCircle(String passwordP, String passwordH) {
    ...
    String res = "some msg";
    webEvent.fire(new SomeWebMessage(res, 0)); 
    mDay.startDay();    
    ...
  }
  

当我从MainDay.initDS()等静态方法的调用中触发事件或者Sheduler调用方法startDay()时,没有NPE(@Schedule(小时=&#34;&#34;,分钟) =&#34;&#34;,second =&#34; / 10&#34;)*。我不知道是什么原因

在不知道您的代码的情况下,这只是猜测,但我假设您在这里注入MainDay或使用CDI / JNDI查找。因此,如果没有实例,容器将创建一个实例,并将注入Event个对象。

答案 1 :(得分:0)

NPE 1:

目标EJB MainDay“不应该”观察“事件并调用其startDay()方法吗?

public void onEvent(@Observes SomeWebMessage event) {
    // if (...)
        startDay();
}

因此不需要静态getInstance()方法。

NPE 2:

@Inject Event<SomeWebMessage> webEvent; 

依赖注入(DI)只有在手动调用构造函数new MainDay()但注入所需bean的实例并让DI容器处理构造时才有效。

但是使用@Observes(javax.enterprise.event.Observes),你应该能够删除所有臭的static内容。