如何在ManagedBean中注入CDI Bean?

arj*_*soh 6 jsf ejb java-ee cdi java-ee-6

我想在ManagedBean中使用注释@Inject或@Produce注入CDI Bean.我使用的CDI Bean是:

@Named
@Startup
@ApplicationScoped
public class BaseBean {

private List<String> custs;

public List<String> getCusts() {
    return custs;
}

public void setCusts(List<String> emps) {
    this.custs = emps;
}

public BaseBean(){

}

@PostConstruct
void init() {
    custs = new ArrayList<String>();
    custs.add("Cust1");
    custs.add("Cust3");
    custs.add("Cust2");
    custs.add("Cust4");
}

}
Run Code Online (Sandbox Code Playgroud)

我想要注入CDI Bean的ManagedBean是:

@SessionScoped
@ManagedBean
public class Hello implements Serializable {

@Inject
private BaseBean dBean;

private static final long serialVersionUID = 1L;
private List<String> customers;
private List<String> customersSelect;

public Hello() {
}

@PostConstruct
void init() {
//  dBean = new BaseBean();
    customers = dBean.getCusts();
}

public List<String> getCustomers() {
    return customers;
}

public List<String> getCustomersSelect() {
    return customersSelect;
}

public void setCustomersSelect(List<String> customersSelect) {
    this.customersSelect = customersSelect;
}
}
Run Code Online (Sandbox Code Playgroud)

但是在init函数中,它会抛出NullPointerException.如果我使用注释@Produces而不是@Inject,结果是相同的:NullPointerException.CDI Bean有什么问题(不正确的注释)?我是否尝试以错误的方式注射它?我的代码缺少什么吗?我怎样才能让它发挥作用?这是JSF代码:

<h:form id ="f">
    <h:selectManyCheckbox layout="pageDirection" border="1"  value="#{hello.customersSelect}">
        <f:selectItems value="#{hello.customers}"></f:selectItems>
    </h:selectManyCheckbox><br />
    <h:commandButton action="response.xhtml" value="Click me" />
</h:form>
Run Code Online (Sandbox Code Playgroud)

PS:如果我使用无状态Bean作为BaseBean并且我用注释@EJB注入它,它没有问题.

更新:我已经与注释尝试了@SessionScoped(javax.enterprise.context.SessionScoped),并@NamedHello类.虽然我没有收到NullPointerException,但是h:selectManyCheckbox空的.此外,它让我感到震惊,当我在beans.xml文件META-INF夹下添加文件时,我收到了一个StartException,虽然该文件应该是.我认为我的应用程序缺乏适当的配置才能进行依赖注入.什么可能需要额外的配置?

更新2:当我在WEB-INF文件夹中添加beans.xml文件时出现此错误.beans.xml文件为空,它只包含以下行:

<?xml version="1.0" encoding="UTF-8"?> 
Run Code Online (Sandbox Code Playgroud)

错误是:

Services which failed to start:      service jboss.deployment.unit."JSF1.war".PARSE: org.jboss.msc.service.StartException in service jboss.deployment.unit."JSF1.war".PARSE: Failed to process phase PARSE of deployment "JSF1.war"

12:51:11,482 ERROR [org.jboss.as.server.deployment.scanner] (DeploymentScanner-threads - 1) {"JBAS014653: Composite operation failed and was rolled back. Steps that failed:" => {"Operation step-2" => {"JBAS014671: Failed services" => {"jboss.deployment.unit.\"JSF1.war\".PARSE" => "org.jboss.msc.service.StartException in service jboss.deployment.unit.\"JSF1.war\".PARSE: Failed to process phase PARSE of deployment \"JSF1.war\""}}}}
Run Code Online (Sandbox Code Playgroud)

rdc*_*rng 9

如果您@Named在CDI bean上使用,@ patlov的建议将起作用.但是,如果您在支持CDI的环境中工作,请不要使用@ManagedBean.相反,一直使用CDI.看到这个答案,我相信你可以找到许多其他强烈反对你想要做的事情.

只需切换javax.faces.bean.SessionScopedjavax.enterprise.context.SessionScoped,一切都将神奇地工作.你可能遇到的是@ViewScopedCDI的缺席,但在这种情况下使用像JBoss Seam或Apache Deltaspike这样的东西为你实现它.作为一个附加的好处,他们也将自动替换所有的JSF与CDI范围自动作用域如果你已经对JSF书面现有的代码.

更新: 这应该是beans.xml的内容:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
Run Code Online (Sandbox Code Playgroud)