【问题标题】:Can CDI inject standard library POJOs into an EJB?CDI 可以将标准库 POJO 注入到 EJB 中吗?
【发布时间】:2015-04-22 19:10:15
【问题描述】:

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

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

我有这个 POJO:

// No annotations
public class SomePojo {   
}

这很好用。如果我将 EJB 注入到 JSF backing-bean 中,我可以看到 somePojo 的值是非空值,正如预期的那样。

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

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 现在:

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

Date 有一个公共的、无参数的构造函数,我认为这就是 CDI “满足依赖关系”所需要的全部内容。我确信这种行为是“规范的”,但显然我对 CDI 的理解存在很大的漏洞。

有人可以解释为什么这不起作用吗?从 CDI 的角度来看,SomePojojava.util.Date 有什么区别?

上下文:

  • Java EE 6
  • GlassFish 3.1.2.2
  • 我没有这方面的用例。我知道我可以指定new Date()

【问题讨论】:

    标签: java ejb cdi


    【解决方案1】:

    我也可以用 EAP 6.3 重现这个。

    这个问题很可能是因为使用了 Java EE 6。java.util.Date 位于 rt.jar 中,并且这个 JAR 不包含可以启用 CDI 的 beans.xml 文件。您只能从包含 beans.xml 的 JAR 中注入对象。

    一种常见的解决方法是使用producer method 来注入这样的对象。您必须自己编写此生产者,但您将能够从任意类中注入对象,而不管它们属于哪个 JAR。

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

    希望对您有所帮助。

    【讨论】:

    • 我会在一两天内在 Glassfish 4 中试用这个并报告。谢谢。
    • EE7 在这种特殊情况下不会改变行为。在 CDI 1.1 中,它会自动发现带有 bean 定义注释的 bean(参见规范的 12.4 Bean Discovery 部分)。 Date 没有定义注解的bean(如@RequestScoped)
    • @jbergmark,我在规范的Bean Archive 部分找到了对您所描述内容的引用:“隐式 bean 存档是包含一个或多个带有 bean 的 bean 类的任何其他存档定义注解……”这其实在roehrijn引用的博文中也有提到:“默认情况下,如果你什么都不指定,也没有beans.xml,则假定bean发现模式是'annotated'而不是'all' 。”谢谢!
    • 我尝试了两件事,它们都起作用了:(1) 添加一个@Produces 方法来生成Date 对象,以及(2) 将java.util.Date 类的副本添加到我的项目中.我意识到第二种方法很奇怪,但它满足了我的好奇心。我想我也可以用beans.xml 文件重新打包rt.jar,然后我可以注入任何STL POJO。第一种方法是我唯一会使用的方法,但这很有启发性。
    • @DavidS:做后者肯定会导致很多额外的问题和异常。你是对的 - 永远不要这样做并使用(1)。
    猜你喜欢
    • 1970-01-01
    • 2012-09-07
    • 2012-10-21
    • 1970-01-01
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    相关资源
    最近更新 更多