尝试在构造函数中访问@Inject bean时出现NullPointerException

eri*_*hak 12 jsf constructor nullpointerexception cdi managed-bean

我有一个会话范围的bean:

@Named
@SessionScoped
public class SessionBean implements Serializable {

    private String someProperty;

    public String getSomeProperty() {
        return someProperty;
    }

}
Run Code Online (Sandbox Code Playgroud)

我想在请求范围的bean中注入它并使用它初始化:

@Named
@RequestScoped
public class RequestBean {

    @Inject
    private SessionBean sessionBean;  

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

}
Run Code Online (Sandbox Code Playgroud)

但是,它会引发以下异常:

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)
    ...
Run Code Online (Sandbox Code Playgroud)

这是怎么造成的,我该如何解决?

Bal*_*usC 24

您期望在构造bean之前注入的依赖项是可用的.你期望它的工作原理如下:

RequestBean requestBean;
requestBean.sessionBean = sessionBean; // Injection.
requestBean = new RequestBean(); // Constructor invoked.
Run Code Online (Sandbox Code Playgroud)

然而,这不是真的,技术上也是不可能的.构造之后注入依赖项.

RequestBean requestBean;
requestBean = new RequestBean(); // Constructor invoked.
requestBean.sessionBean = sessionBean; // Injection.
Run Code Online (Sandbox Code Playgroud)

@PostConstruct如果您打算在构造bean之后直接基于注入的依赖项执行业务逻辑,则应该使用方法.

删除构造函数并添加此方法:

@PostConstruct
public void init() {
    System.out.println(sessionBean.getSomeProperty());
}
Run Code Online (Sandbox Code Playgroud)

  • 您仍在使用构造函数。去掉它。重新阅读答案的第一部分。我还建议在继续使用 JSF 之前暂停一下 JSF 并[学习一些基本的 Java](http://docs.oracle.com/javase/tutorial/)。 (2认同)