2017-04-03 55 views
1

我需要使用依賴注入來從某些ejb(無狀態和單例)引發事件。我不使用Spring,Guice等。 問題是,當通過getInstance()調用其方法時,我在其中一個bean中獲得NPE。以下是代碼片段:Singleton CDI @Inject空指針異常

@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> 

有當我從火災事件沒有NPE一個像MainDay.initDS()這樣的靜態方法的調用,或者當Sheduler調用方法startDay()時(@Schedule(hour =「」,minute =「」,second = 「/10」)*。 我不知道是什麼原因

回答

0

注意@Singleton意味着容器(EJB或CDI,取決於它是註釋)將管理實例,即不應該自己創建它。

如果通過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();  
    ... 
    } 

沒有NPE,當我從靜態方法像MainDay.initDS呼叫火災事件()或方法時朝九特派()由Sheduler(@Schedule(小時援引=「」,分=「」,第二=「/ 10」)。*我不知道是什麼原因

不知道你的代碼是隻是一個猜測,但我假設你在這裏注入MainDay或使用CDI/JNDI查找,因此t他的容器將創建一個實例,如果沒有,並將注入Event對象。

+0

謝謝托馬斯!現在,它清晰,它的工作原理:) – Buch

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。觀察)你應該能夠刪除所有的臭臭static的東西無論如何。

+0

還有另外一個單是觀察在ControllerStartStop,MainDay觸發的事件,也許一兩個人: '@辛格爾頓 公共類LongPollingNotifier { \t私人最終隊列同行=新的ConcurrentLinkedQueue (); @Asynchronous \t公共無效notifyPeers(@Observes SomeWebMessage SWM)... ' 是這種方法好嗎? – Buch

+0

是的,你可以有多個獨立的觀察者。 –