通过构造函数的依赖注入对EJB bean不起作用

问题描述 投票:1回答:3

我的应用程序正在部署到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 class com.demo.app.UserService必须具有不带参数的公共构造函数

我记得EJB规范中有一些内容说:the class must have a public constructor that takes no parameters,对我来说有意义的是bean实例首先由容器实例化,然后完成依赖注入。

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

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

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

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

有任何想法吗? :)

java java-ee dependency-injection ejb weld
3个回答
3
投票

所以会发生什么是你不满足初始化EJB bean的要求。

CDI规范对构造函数有一些限制 - 无论是args还是@Inject。但是也有this chapter,它指定在EE中,规则集由EJB会话bean所需的扩展。

现在我们进入EJB规范,它需要bean上的无参数构造函数。这应该在章节Enterprise Bean Class中说明

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

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


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服务”。 .... Weld预先使用EjbInjectionServices,JpaInjectionServices,ResourceInjectionServices和JaxwsInjectionServices实现注册资源注入点(在引导程序中)。这允许在引导时而不是运行时验证资源注入点

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


2
投票

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

我想它只是提供了无参数构造函数。

© www.soinside.com 2019 - 2024. All rights reserved.