如何在ManagedBean中注入CDI Bean? [英] How to inject a CDI Bean in a ManagedBean?

查看:161
本文介绍了如何在ManagedBean中注入CDI Bean?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用注释@Inject或@Produce在ManagedBean中注入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);
}

}

ManagedBean,注入CDI Bean是:

  @SessionScoped 
@ManagedBean
public class Hello implements Serializable {

@Inject
private BaseBean dBean;

private static final long serialVersionUID = 1L;
私人列表< String>顾客;
私人列表< String> customersSelect;

public Hello(){
}

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

public List< String> getCustomers(){
返回客户;
}

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

public void setCustomersSelect(List< String> customersSelect){
this.customersSelect = customersSelect;
}
}

然而,在init函数中,它抛出NullPointerException。如果我使用注释@Produces而不是@Inject,结果是相同的:NullPointerException。 CDI Bean有什么问题(不正确的注释)吗?我试图用错误的方式注入它吗?我的代码缺少什么吗?我该如何让它工作?以下是JSF代码:

 < h:form id =f> 
< h:selectManyCheckbox layout =pageDirectionborder =1value =#{hello.customersSelect}>
< f:selectItems value =#{hello.customers}>< / f:selectItems>
< / h:selectManyCheckbox>< br />
< h:commandButton action =response.xhtmlvalue =点击我/>
< / h:form>

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



更新:我已尝试使用注释 @SessionScoped javax.enterprise.context.SessionScoped )和 @Named Hello 类。虽然我没有收到一个 NullPointerException ,但是 h:selectManyCheckbox 是空的。此外,它触发了我,当我在 META-INF 文件夹下添加 beans.xml 文件时,我收到一个 StartException ,虽然该文件应该是。我认为我的应用程序缺乏正确的配置才能够依赖注入。什么可能需要额外的配置?



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

 <?xml version =1.0encoding = UTF-8\" >?; 

错误是:

 无法启动的服务:service jboss.deployment.unitJSF1.war.PARSE:org.jboss.msc.service.StartException in service jboss.deployment.unitJSF1.war .PARSE:处理阶段PARSE无法处理JSF1.war

12:51:11,482 ERROR [org.jboss.as.server.deployment.scanner](DeploymentScanner-threads - 1){ JBAS014653:复合操作失败并被回滚。失败的步骤:=> {操作步骤2=> {JBAS014671:Failed services=> {jboss.deployment.unit.\JSF1.war\.PARSE=> org.jboss.msc.service.StartException in service jboss.deployment.unit.\JSF1.war\.PARSE:无法处理相位PARSE部署\JSF1.war\}}} }


解决方案

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



只需从 javax.faces.bean切换。 SessionScoped javax.enterprise.context.SessionScoped ,一切都会神奇地工作。可能会遇到的是CDI中的$ code> @ViewScoped 的缺失,在这种情况下,请使用JBoss Seam或Apache Deltaspike来实现它。作为一个附加的好处,如果您已经为JSF编写了现有的代码,他们还将自动替换所有具有CDI范围的JSF范围。



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

 <?xml version =1.0 encoding =UTF-8?> 
< beans xmlns =http://java.sun.com/xml/ns/javaeexmlns:xsi =http://www.w3.org/2001/XMLSchema-instancexsi:schemaLocation =http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd\">
< / beans>


I want to inject a CDI Bean in a ManagedBean either with the annotation @Inject or @Produce. The CDI Bean which I use is:

@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");
}

}

The ManagedBean, in which I want to inject the CDI Bean is:

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

In the init function however, it throws NullPointerException. If I use the annotation @Produces instead of @Inject, the result is the same: NullPointerException. Is anything wrong with the CDI Bean (improper annotations)? Do I try to inject it with a wrong way? Does my code lack of something? How can I get it work? Here is the JSF code:

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

PS: If I use a Stateless Bean as BaseBean and I inject it with the annotation @EJB, it works with no problem.

UPDATE: I have tried it with the annotations @SessionScoped (javax.enterprise.context.SessionScoped) and @Named on the Hello class. Although I do not receive a NullPointerException, the h:selectManyCheckbox is empty. moreover, it strikes me, that when I add the beans.xml file under META-INF folder, I receive a StartException, although the file is there supposed to be. I think my application lacks the proper configuration to be capable of Dependency Injection. What is likely to need additional configuration?

UPDATE 2: This error appears when I add the beans.xml file in the WEB-INF folder. The beans.xml file is empty, it contains only the line :

<?xml version="1.0" encoding="UTF-8"?> 

The error is:

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\""}}}}

解决方案

What @patlov is suggesting will work if you use @Named on your CDI beans. However, if you're working in an environment that supports CDI, do not use @ManagedBean. Instead, use CDI all the way. See this answer and I'm sure you could find numerous other ones that strongly advise against what you're trying to do.

Just switch from javax.faces.bean.SessionScoped to javax.enterprise.context.SessionScoped and everything will magically work. What you may run into is the absense of @ViewScoped from CDI however, in which case use something like JBoss Seam or Apache Deltaspike that implement it for you. As an added benefit, they will also automatically replace all of the JSF scopes with CDI scopes automatically if you already have existing code written for JSF.

Update: This should be the content of your 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>

这篇关于如何在ManagedBean中注入CDI Bean?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆