CDI可以将标准库POJO注入EJB吗?

问题描述:

我可以将自己的POJO注入到这样的管理对象中:

I can inject my own POJO into a managed object like this:

import javax.ejb.Stateless;
import javax.inject.Inject;
@Stateless
public class SomeEjb {
    @Inject
    private SomePojo somePojo;
}

我有这个POJO:

// No annotations
public class SomePojo {   
}

这工作正常。如果我将EJB注入到JSF后台bean中,我可以看到 somePojo 的值是非空值,如预期的那样。

This works fine. If I inject the EJB into a JSF backing-bean, I can see that the value of somePojo is non-null value, as expected.

但是,如果我尝试将 java.util.Date 注入到 SomeEjb 中,我在部署时收到以下异常:

However, if I try to inject a java.util.Date into SomeEjb, I get the following exception on deployment:

Severe: Exception while loading the app : WELD-001408 Unsatisfied dependencies for type [Date] with qualifiers [@Default] at injection point [[field] @Inject private SomeEjb.date]
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Date] with qualifiers [@Default] at injection point [[field] @Inject private SomeEjb.date]
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:311)

SomeEjb now:

SomeEjb now:

// No annotations
public class SomeEjb {
    @Inject
    private Date date;    
}

Date有一个public,无参数的构造函数,我以为这是所有的CDI需要满足依赖。我确信这个行为是规范,但是我明白CDI的理解显然有一个很大的洞。

Date has a public, no-argument constructor, and I thought that's all CDI would need to "satisfy the dependency". I'm sure this behaviour is "to spec", but clearly there's a big hole in my understanding of CDI.

有人可以解释为什么这不行吗?来自CDI透视图的 SomePojo java.util.Date 有什么区别?

Can someone explain why this doesn't work? What's the difference between SomePojo and java.util.Date from a CDI perspective?

上下文:


  • Java EE 6

  • GlassFish 3.1.2.2

  • 我没有这个用例。我知道我可以指定 new Date()

  • Java EE 6
  • GlassFish 3.1.2.2
  • I don't have a use-case for this. I know that I can just specify new Date().

我可以用EAP 6.3再现这个。

I can reproduce this with EAP 6.3 as well.

这个问题最有可能是由于使用Java EE 6而发生的。java.util。日期位于rt.jar中,此JAR不包含将启用CDI的beans.xml文件。您只能从包含beans.xml的JAR中注入对象。

The problem most likely occurs because of using Java EE 6. The java.util.Date is located in rt.jar and this JAR does not contain a beans.xml file which would enable CDI. You can only inject objects from JARs containing a beans.xml.

常见的解决方法是使用 producer方法来注入这样一个对象。你必须自己修理这个制作人,但是你可以从任意类注入对象,而不管他们属于哪个JAR。

A common workaround is to use a producer method to inject such an object. You have to wirte this producer yourself but you will be able to inject objects from arbitrary classes regardless to which JAR they belong.

据我所知,Java中的行为发生了变化EE 7,其中beans.xml在某些情况下是可选的: https://blogs.oracle.com / theaquarium / entry / default_cdi_enablement_in_java

As far as I know the behaviour changed in Java EE 7, where the beans.xml is optional in some cases: https://blogs.oracle.com/theaquarium/entry/default_cdi_enablement_in_java

希望有所帮助。