通过构造函数进行的依赖注入不适用于EJB bean

时间:2018-11-19 14:27:02

标签: java java-ee dependency-injection ejb weld

我的应用程序正在部署到IBM WebSphere上。我有一个简单的服务,我想知道在这种情况下依赖注入的工作原理。

// stateless EJB
@Stateless
public class UserService {

    private UserDAO userDAO;

    // btw, UserDAO is stateless EJB as well
    @Inject
    public UserService(UserDAO userDAO) {
        this.userDAO = userDAO;    
    }

    // biz methods ...
}

它失败并出现以下错误:

  

[错误] CWWKZ0002E:启动计算机时发生异常   应用程序my-app。异常消息为:   com.ibm.ws.container.service.state.StateChangeException:   com.ibm.ws.cdi.CDIException:   com.ibm.wsspi.injectionengine.InjectionException:   com.ibm.ejs.container.EJBConfigurationException:EJB类   com.demo.app.UserService必须具有一个   不带参数的公共构造函数

我记得EJB规范中有一句话:the class must have a public constructor that takes no parameters,对我来说, bean实例首先由容器实例化,然后进行依赖注入。 / p>

另一方面,我在WELD文档中发现了这一点:

  

首先,容器调用bean构造函数(默认   构造函数或带注释的@Inject),以获取的实例   豆。

我有点困惑,为什么无法实例化我的EJB。

当我们有构造函数注入点时,如何创建EJB实例并注入依赖项?

有什么想法吗? :)

3 个答案:

答案 0 :(得分:3)

EJB会话Bean的创建是由EJB容器完成的,但是它可以选择使用CDI提供EE资源注入,但是EJB解析则委托给了容器

https://docs.jboss.org/weld/reference/2.1.0.Final/en-US/html/ri-spi.html说:

  

或者,集成商可以选择使用CDI提供EE   资源注入。在这种情况下,EE_INJECT环境应为   使用,集成商应实现第A.1.4节“ EJB   服务”,第A.1.7节“资源服务”和第A.1.5节“ JPA”   服务”。       ....
  焊接将资源注入点注册到   EjbInjectionServices,JpaInjectionServices,ResourceInjectionServices   和JaxwsInjectionServices实施(在引导程序中)。   这允许在以下位置执行资源注入点的验证   启动时间而不是运行时间

如果您对CDI和EJB的集成方式感兴趣。您可以看一下weld-EJB模块和weld-integration的代码(glassfish代码)

答案 1 :(得分:3)

所以发生的事情是您不满足初始化EJB bean的要求。

CDI规范对构造函数有一些限制-无参数或带有@Inject的参数。 但是还有this chapter,它指定在EE中,EJB会话bean所要求的规则集得到了扩展。

现在我们进入EJB规范,该规范要求在bean上使用no-arg构造函数。 这应该在Enterprise Bean Class章中指出

  

该类必须定义一个不带参数的公共构造函数。

现在,最后继续讨论这是否应该起作用-例如使用CDI构造函数注入可以拥有EJB bean吗? 好吧,让我们看一下CDI TCK,这是所有实现和容器都必须通过的一组测试,以便能够声明它们实现了CDI。 在那里,我们可以看到this beanthis test using it-是的,这可以工作,但是您需要同时拥有两个构造函数。

答案 2 :(得分:2)

EJB被注册为CDI bean。但是首先,它们必须满足EJB规范的要求。

我想它只是通过提供no-args构造函数而起作用。