通过构造函数的依赖注入不适用于 EJB bean
Dependency injection through constructor does not work for EJB bean
我的应用程序正在部署到 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 ...
}
失败并出现以下错误:
[ERROR ] CWWKZ0002E: An exception occurred while starting the
application my-app. The exception message was:
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 must have a
public constructor that takes no parameters
我记得 EJB 规范中有这样的内容:the class must have a public constructor that takes no parameters
bean 实例首先由容器实例化,然后依赖注入完成,这对我来说很有意义.
另一方面,我在 WELD 文档中找到了这个:
First, the container calls the bean constructor (the default
constructor or the one annotated @Inject), to obtain an instance of
the bean.
而且我有点困惑,为什么我的 EJB 无法实例化。
当我们有构造函数注入点时,如何创建 EJB 实例和注入依赖项?
有什么想法吗? :)
EJB 注册为 CDI bean。但首先它们必须满足 EJB 规范的要求。
我猜它只是通过提供无参数构造函数来工作。
EJB 会话 bean 的创建是由 EJB 容器完成的,但它可以选择使用 CDI 来提供 EE 资源注入,但 EJB 解析委托给容器
https://docs.jboss.org/weld/reference/2.1.0.Final/en-US/html/ri-spi.html 说:
Alternatively, the integrator may choose to use CDI to provide EE
resource injection. In this case, the EE_INJECT environment should be
used, and the integrator should implement the Section A.1.4, “EJB
services”, Section A.1.7, “Resource Services” and Section A.1.5, “JPA
services”.
....
Weld registers resource injection points with
EjbInjectionServices, JpaInjectionServices, ResourceInjectionServices
and JaxwsInjectionServices implementations upfront (at bootstrap).
This allows validation of resource injection points to be performed at
boot time rather than runtime
如果您对 CDI 和 EJB 的集成方式感兴趣。你可以看看weld-EJB模块和weld-integration的代码(glassfish代码)
那么发生的事情是你不满足初始化EJB beans的要求。
CDI 规范对构造函数有一些限制 - 无参数或带有 @Inject
的构造函数。
但还有 this chapter,它指定在 EE 中,规则集根据 EJB 会话 bean 的要求进行扩展。
现在我们将进入 EJB 规范,它需要 bean 上的无参数构造函数。
这应该在第 Enterprise Bean Class
章中,其中说明
The class must define a public constructor that takes no arguments.
现在,终于开始讨论这是否可行 - 例如你能有一个使用 CDI 构造函数注入的 EJB bean 吗?
好吧,让我们看一下 CDI TCK,这是一组测试,所有实现和容器都必须通过这些测试才能声称它们实现了 CDI。
在那里,我们可以看到 this bean and this test using it - 是的,这可以工作,但你需要同时拥有两个构造函数。
我的应用程序正在部署到 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 ...
}
失败并出现以下错误:
[ERROR ] CWWKZ0002E: An exception occurred while starting the application my-app. The exception message was: 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 must have a public constructor that takes no parameters
我记得 EJB 规范中有这样的内容:the class must have a public constructor that takes no parameters
bean 实例首先由容器实例化,然后依赖注入完成,这对我来说很有意义.
另一方面,我在 WELD 文档中找到了这个:
First, the container calls the bean constructor (the default constructor or the one annotated @Inject), to obtain an instance of the bean.
而且我有点困惑,为什么我的 EJB 无法实例化。
当我们有构造函数注入点时,如何创建 EJB 实例和注入依赖项?
有什么想法吗? :)
EJB 注册为 CDI bean。但首先它们必须满足 EJB 规范的要求。
我猜它只是通过提供无参数构造函数来工作。
EJB 会话 bean 的创建是由 EJB 容器完成的,但它可以选择使用 CDI 来提供 EE 资源注入,但 EJB 解析委托给容器
https://docs.jboss.org/weld/reference/2.1.0.Final/en-US/html/ri-spi.html 说:
Alternatively, the integrator may choose to use CDI to provide EE resource injection. In this case, the EE_INJECT environment should be used, and the integrator should implement the Section A.1.4, “EJB services”, Section A.1.7, “Resource Services” and Section A.1.5, “JPA services”. ....
Weld registers resource injection points with EjbInjectionServices, JpaInjectionServices, ResourceInjectionServices and JaxwsInjectionServices implementations upfront (at bootstrap). This allows validation of resource injection points to be performed at boot time rather than runtime
如果您对 CDI 和 EJB 的集成方式感兴趣。你可以看看weld-EJB模块和weld-integration的代码(glassfish代码)
那么发生的事情是你不满足初始化EJB beans的要求。
CDI 规范对构造函数有一些限制 - 无参数或带有 @Inject
的构造函数。
但还有 this chapter,它指定在 EE 中,规则集根据 EJB 会话 bean 的要求进行扩展。
现在我们将进入 EJB 规范,它需要 bean 上的无参数构造函数。
这应该在第 Enterprise Bean Class
章中,其中说明
The class must define a public constructor that takes no arguments.
现在,终于开始讨论这是否可行 - 例如你能有一个使用 CDI 构造函数注入的 EJB bean 吗? 好吧,让我们看一下 CDI TCK,这是一组测试,所有实现和容器都必须通过这些测试才能声称它们实现了 CDI。 在那里,我们可以看到 this bean and this test using it - 是的,这可以工作,但你需要同时拥有两个构造函数。