【问题标题】:@Injection is not working for CDI bean@Injection 不适用于 CDI bean
【发布时间】:2012-09-11 11:40:29
【问题描述】:

我有一个使用@ConversationScoped 的CDI bean。当我尝试为 Conversation 对象执行 @Inject 时,我得到了 NPE。

  @ConversationScoped
@Named("customerbean")
public class CustomerBean implements Serializable {

    @Inject
    private Conversation conversation;    

    private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("ba");
    private EntityManager em;
    private Customer customer;
    boolean disabled;    

    public CustomerBean() {
        beginConversation();
        customer = new Customer();
        em = emf.createEntityManager();
        disabled = false;
    }

    private void beginConversation() {
        if (this.conversation.isTransient()) {
            this.conversation.begin();
            return;
        }
        throw new IllegalStateException();
    }

我在 WEB-INF 目录中有 beans.xml 文件(虽然是空的)。异常如下所示:

INFO: Exception when handling error trying to reset the response.
com.google.common.collect.ComputationException: java.lang.RuntimeException: java
.lang.NullPointerException
        at com.google.common.collect.ComputingConcurrentHashMap$ComputingMapAdap
ter.get(ComputingConcurrentHashMap.java:397)
        at org.jboss.weld.bean.proxy.ClientProxyProvider.getClientProxy(ClientPr
oxyProvider.java:102)
        at org.jboss.weld.el.AbstractWeldELResolver.lookup(AbstractWeldELResolve
r.java:115)
        at org.jboss.weld.el.AbstractWeldELResolver.getValue(AbstractWeldELResol
ver.java:96)
        at org.jboss.weld.environment.servlet.util.ForwardingELResolver.getValue
(ForwardingELResolver.java:49)
        at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:67)
        at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELR
esolver.java:176)

【问题讨论】:

  • 如何在代码中创建/访问CustomerBean
  • @Erhan:对话是对 JSR 299 规范要求的特殊托管 bean 的引用。
  • @Thorbjörn - 我认为 OP 不知道 CDI bean 的生命周期,只是混淆了他的 bean 的初始化。但是更多的代码肯定会有所帮助
  • @Aaron:我通过访问它在我的 xhtml 文件中使用它。我假设它在第一次访问时由框架初始化。但是,在我意识到即使我有 ConversationScoped 后,我的“问题”开始出现,它的行为就像它具有 Session 范围一样。进一步阅读后,我了解到我必须执行 begin() 方法才能让框架了解我想要一个长时间运行的 bean。现在,当我尝试将对话注入 bean 时,我得到了 NPE。
  • @Jan:你说得对,我是 CDI/JSF 的新手。我以前在其他项目中使用过 Struts/Spring。

标签: java jsf cdi


【解决方案1】:

您不得使用new 创建 CDI bean,也不得将构造函数用于任何类型的初始化逻辑。

这背后的原因是 CDI bean(如 EJB、Spring bean、JSF bean)具有独立的生命周期并由相关容器管理。您不能依赖于何时(以及多久)调用new 的“传统”理解。使用生产者创建新的 bean,并使用@PostConstruct 进行创建后要执行的任何逻辑。

This 应该让您有一个良好的 CDI 开始。随时发布更多问题:)

【讨论】:

  • 这不是评论吗?
  • 至少它不打算成为一个。我指的是OP在构造函数中放入了逻辑,这是完全错误的,导致他可能没有理解CDI的基本原理的假设......
  • 好的,我把初始化逻辑移到了一个 postconstruct 方法中。它现在似乎正在初始化。谢谢!
【解决方案2】:

正如 Jan 所说,您正在将逻辑添加到构造函数中。直到调用构造函数之后才会发生注入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-20
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    • 2018-10-10
    • 2015-04-20
    相关资源
    最近更新 更多