【问题标题】:Instance null after injecting @SessionScoped CDI bean into a JSF @ManagedBean将@SessionScoped CDI bean 注入 JSF @ManagedBean 后的实例 null
【发布时间】:2019-06-04 10:44:03
【问题描述】:

我有: - 存储库类:

@SessionScoped
public class EmployeeRepository {
    @PersistenceContext
    EntityManager entityManager;
    public List<Employee> getEmployees(){
        TypedQuery<Employee> qu = entityManager.createQuery("select * from Employee", Employee.class);
        List<Employee> emp2 = qu.getResultList();
        return emp2;
    }
}

托管 Bean:

@ManagedBean(name = "helloWorldBean")
public class HelloWorldBean {
    @Inject
    private EmployeeRepository employeerepo;
    public String getMsg() {
        return "Hallo";
    }
    public String getEmployees() {
        return String.valueOf(employeerepo.getEmployees().size());
    }
}

还有一个 JSF 页面:

<h:head>
    <title>JavaCodeGeeks</title>
</h:head>
<h:body>
    - Message : <h:outputText value="#{helloWorldBean.msg}" />
    - Employee count : <h:outputText value="#{helloWorldBean.employees}" />
</h:body>
</html>

我的 META-INF 文件夹 (src\META-INF) 中有一个 beans.xml,没有特殊配置:

<?xml version="1.0"?>
<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"
  bean-discovery-mode="all" version="1.1">
</beans>

问题:

页面抛出空指针异常,因为 EmployeeRepository 没有注入 HelloWorldBean。

在我的情况下如何注入类的实例?

【问题讨论】:

  • 您使用的是哪个版本的 CDI?
  • javaee-api-6.0.jar 。 bean_1_1.xsd。我的 beans.xml 在 src\META-INF\
  • 好的,bean_1_1 是 CDI 1.1。您在 beans.xml 中有 bean-discovery-mode 属性吗?哪个是价值?顺便说一句,CDI 1.1 是 Java EE 7,而你有 Java EE 6 api...
  • 我已将 beans.xml 的内容添加到问题中。感谢您的帮助。
  • 您使用的是哪个应用服务器或 servlet 容器(和版本)?

标签: jsf cdi inject


【解决方案1】:

当您使用 CDI 时,您不应该使用 @ManagedBean(这是一个 JSF 注释)。虽然我实际上已经看到了这种工作方式,但大多数实现都不允许您将 CDI bean 注入经典的 JSF bean。

为了允许在 JSF bean 中注入 CDI,CDI 规范允许您通过指定 @Named 注释和范围(@RequestScoped@javax.faces.view.ViewScoped@SessionScoped@ApplicationScoped)来定义 JSF 支持 bean )。

总之,下面这段代码应该可以解决你的问题,

@Named
@RequestScoped
public class HelloWorldBean {
    @Inject
    private EmployeeRepository employeerepo;
    public String getMsg() {
        return "Hallo";
    }

    public String getEmployees() {
        return String.valueOf(employeerepo.getEmployees().size());
    }
}

您还可以通过网站上的一些旧 Q/A 进一步了解该主题,

How to inject a CDI Bean in a ManagedBean?

@ManagedProperty does not work in a CDI managed bean

CDI beans injection

【讨论】:

  • 感谢您的帮助。使用新代码,xhtml 似乎找不到我的 bean。不调用 HelloWorldBean。有什么帮助吗?
  • @mcflysoft 确保您致电 helloWorldBean 而不是 HelloWorldBean。任何类名都将获得一个带有驼峰式表示法的变量(除非您明确指定要命名它的内容)。还要确保在完全支持 CDI 的环境中运行应用程序。 Tomcat 7 不是开箱即用的,需要额外的配置。我建议您研究一个成熟的 JavaEE 服务器,该服务器具有 JavaEE / JakartaEE 的最新实现,例如 Payara、GlassFish 或 WildFly。
  • 或 TomEE ;-) 是的,实际上这是一个新问题 fpr,其中有几个相关的 q/an stackoverflow
  • @Kukeltje 这些天来,TomEE 完全是最新的吗?上次我尝试它时,我不得不四处乱逛并做很多额外的配置步骤来让一切正常工作。
  • 上次我尝试它的时候还不错,但这只是在没有 jms 的情况下尝试使用 cdi、jsf、ejb 和 1.5 年前。我通常使用 Wildfly。
猜你喜欢
  • 2016-08-02
  • 2016-12-04
  • 1970-01-01
  • 2019-08-04
  • 2015-04-15
  • 1970-01-01
  • 2013-11-26
相关资源
最近更新 更多