当前位置: 首页 > 知识库问答 >
问题:

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

陈弘厚
2023-03-14

我的应用程序正在部署到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。国际商用机器公司ws。容器服务状态StateChangeException:com。国际商用机器公司ws。cdi。CDIException:com。国际商用机器公司wsspi。注射引擎。注射异常:com。国际商用机器公司ejs。容器EJBConfiguration异常:EJB类com。演示。应用程序。UserService必须具有不接受任何参数的公共构造函数

我记得EJB规范中有这样一句话:这个类必须有一个不带参数的公共构造函数,对我来说,bean实例首先由容器实例化,然后进行依赖注入是有道理的。

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

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

我有点困惑,为什么我的EJB不能实例化。

当我们有构造html" target="_blank">函数注入点时,如何创建EJB实例和注入依赖项?

任何想法?:)

共有3个答案

王轶
2023-03-14

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_注入环境,集成商应该实现A.1.4节“EJB服务”、A.1.7节“资源服务”和A.1.5节“JPA服务”
Weld通过EjbInjectionServices、JpaInjectionServices、ResourceInjectionServices和JaxwsInjectionServices实现预先(在引导时)注册资源注入点。这允许在启动时而不是运行时执行资源注入点的验证

如果您对如何集成CDI和EJB感兴趣。您可以看看weld EJB模块和weld集成的代码(glassfish代码)

楚泳
2023-03-14

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

我猜它只是通过提供无参数构造函数来工作。

郜彬
2023-03-14

所以发生的情况是,您不符合初始化EJB bean的要求。

CDI规范对构造函数有一些限制——要么没有参数,要么带有@Inject。但本章也规定了在EE中,规则集是根据EJB会话bean的要求进行扩展的。

现在我们进入EJB规范,它要求bean上有一个无参数构造函数。这应该在企业Bean类一章中说明

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

现在,最后讨论这是否应该起作用——例如,您可以使用CDI构造函数注入来创建EJB bean吗?好的,让我们看看CDI TCK,这是一组测试,所有实现和容器都必须通过,才能声明它们实现了CDI。在这里,我们可以看到这个bean和使用它的这个测试——是的,这可以工作,但是你需要两个构造函数。

 类似资料:
  • 我使用Spring Boot开发了REST服务。在其中一个REST控制器中,我有一个基于字段的依赖注入,我想将其更改为基于构造函数的依赖注入。我的依赖注入设置目前如下所示: 使用此设置,一切正常。我想将ParameterDateService更改为基于构造函数,我尝试了以下方法: 更改为基于构造函数的依赖注入后,当我尝试像这样注入依赖时,我会得到一个参数数据ervice.post参数日期(参数日期

  • 当容器调用具有许多参数的类构造函数时,完成基于构造函数的DI,每个参数表示对另一个类的依赖。 例子 (Example) 以下示例显示了一个类TextEditor ,它只能通过构造函数注入进行依赖注入。 让我们有一个可用的Eclipse IDE,并按照以下步骤创建一个Spring应用程序 - 脚步 描述 1 创建一个名为SpringExample的项目,并在创建的项目中的src文件夹下创建一个包co

  • 在之前的所有JUnit版本中,测试构造函数或方法都不允许有参数(至少不能使用标准的Runner实现)。作为JUnit Jupiter的主要变化之一,测试构造函数和方法现在都允许有参数。这带来了更大的灵活性,并为构造函数和方法启用依赖注入。 ParameterResolver定义了测试扩展的API,希望在运行时动态解析参数。如果测试构造函数或@Test, @TestFactory, @BeforeE

  • 我需要重构现有的抽象类来实现依赖注入,但是这个类有两个接受其他参数的构造函数。 我需要注入一些接口,并避免在构造函数中传递任何其他参数,如“settingsId”和“Setting”。所以我的想法是在创建此类的实例后创建两种方法来设置这些参数。 但它看起来不是一个合适的解决方案,因为如果开发人员忘记在创建实例后运行这些方法之一,我们将来可能会得到一个异常(对象未设置为引用...)。我应该如何正确执

  • 我正试图在计算机上实现这个例子https://developer.android.com/jetpack/docs/guide.这就解释了Android应用程序的结构。 当我使用相同的代码时,我会出现以下错误。 我可以找出这个错误与 当我为ViewModel编写默认的零输入构造函数时,我得到了以下错误。 我想不出这个错误的原因和解决方法。