java @Injection 不适用于 CDI bean

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12368888/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 08:36:35  来源:igfitidea点击:

@Injection is not working for CDI bean

javajsfcdi

提问by javaMS

I have a CDI bean where I'm using @ConversationScoped. When I try to do an @Inject for the Conversation object, I get a NPE.

我有一个 CDI bean,我在其中使用 @ConversationScoped。当我尝试为 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();
    }

I have the beans.xml file (although empty) in the WEB-INF directory. The exception looks like this:

我在 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)

回答by jan groth

You must not create a CDI bean using new, nor use a constructor for any sort of initialization logic.

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

The reason behind this is that CDI beans (like EJBs, Spring beans, JSF beans) have an independent lifecycle and are managed by the relevant container. You cannot rely on the "traditional" understanding of when (and how often) newwill be called. Use producers to create new beans, and use @PostConstructfor any logic to be performed after creation.

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

Thisshould give you a good start with CDI. Feel free to post further questions :)

应该会给您一个良好的 CDI 开端。随时发布更多问题:)

回答by LightGuard

As Jan says, you're adding logic into the constructor. Injection doesn't happen until after the constructor is called.

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