2013-05-06 18 views
11

Mam sesja scoped fasola:NullPointerException podczas próby dostępu @Inject fasoli w konstruktorze

@Named 
@SessionScoped 
public class SessionBean implements Serializable { 

    private String someProperty; 

    public String getSomeProperty() { 
     return someProperty; 
    } 

} 

Chciałbym wstrzyknąć to we wniosku o zakresie fasoli i zainicjować z nim:

@Named 
@RequestScoped 
public class RequestBean { 

    @Inject 
    private SessionBean sessionBean; 

    public RequestBean() { 
     System.out.println(sessionBean.getProperty()); 
    } 

} 

jednak rzuca następujący wyjątek:

java.lang.NullPointerException 
    at com.example.RequestBean.<init>(RequestBean.java:42) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525) 
    at org.jboss.weld.introspector.jlr.WeldConstructorImpl.newInstance(WeldConstructorImpl.java:206) 
    at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:117) 
    at org.jboss.weld.bean.ManagedBean.createInstance(ManagedBean.java:336) 
    at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget.produce(ManagedBean.java:200) 
    at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:292) 
    ... 

Jak to jest spowodowane i jak mogę go rozwiązać?

+0

zależność można wstrzykiwać tylko raz instancji jest zrobione, ale używasz go w konstruktorze. Spróbuj wykonać kod po zakończeniu budowy. –

+0

Zrobiłem. ten sam wynik. –

+0

Uważam, że nie zrozumiałeś części "po budowie". Powinieneś użyć metody '@ PostConstruct' i absolutnie nie wywoływać jej z wnętrza konstruktora. – BalusC

Odpowiedz

22

Spodziewasz się, że zależność wstrzykiwana jest dostępna przed utworzeniem fasoli. Spodziewamy się, że działa tak:

RequestBean requestBean; 
requestBean.sessionBean = sessionBean; // Injection. 
requestBean = new RequestBean(); // Constructor invoked. 

Nie jest to jednak prawdą i technicznie niemożliwe. Zależności są wstrzykiwane po konstrukcji.

RequestBean requestBean; 
requestBean = new RequestBean(); // Constructor invoked. 
requestBean.sessionBean = sessionBean; // Injection. 

należy używać metody @PostConstruct zamiast jeśli zamierzają wykonywać logikę biznesową opartą na zależnościach wstrzykiwane bezpośrednio po zakończeniu budowy fasoli.

Usuń konstruktor i dodać tę metodę: Odpowiedz

@PostConstruct 
public void init() { 
    System.out.println(sessionBean.getSomeProperty()); 
} 
+0

Edytowałem pytanie, próbowałem używać PostConstruct i wciąż ten sam wynik. –

+1

Wciąż używasz konstruktora. Usunąć to. Przeczytaj ponownie pierwszą część odpowiedzi. Proponowałbym również przerwę w JSF i [nauczyć się podstawowej Java] (http://docs.oracle.com/javase/tutorial/) przed kontynuowaniem JSF. – BalusC

1

BalusC jest poprawna, ale nie odzwierciedla fazę przypisanie stworzenia obiektu, który nie prowadził w tym czasie. Ale w każdym razie CDI fasoli powinny być dostępne, jeśli grep go programowo poprzez:

javax.enterprise.inject.spi.CDI.current().select(SessionBean.class).get()