【发布时间】:2018-01-23 20:42:23
【问题描述】:
我正在尝试将构造函数注入模式应用于我的 CDI 应用程序中的 bean,但遇到以下错误消息:
15:18:11,852 ERROR [izone.adams.webapp.error.IzoneExceptionHandler] (default task-40) org.jboss.weld.exceptions.UnproxyableResolutionException: WELD-001435: Normal scoped bean class webapp.util.LoginManagerAction is not proxyable because it has no no-args constructor - <unknown javax.enterprise.inject.spi.Bean instance>.
at org.jboss.weld.bean.proxy.DefaultProxyInstantiator.validateNoargConstructor(DefaultProxyInstantiator.java:50)
确实,为了使用构造函数注入模式,我特意设计了我的类,其中包含一个需要参数的构造函数:
@ApplicationScoped
@Typed(LoginManagerAction.class)
public class LoginManagerAction extends UtilBasicDispatchAction {
@Inject
public LoginManagerAction( SessionManager sessionManager, JMSHealthCheckService jmsHealthCheckService) {
super();
this.sessionManager = sessionManager;
this.jmsHealthCheckService = jmsHealthCheckService;
}
...
...
}
查看CDI Specs of Unproxyable bean types,我看到了:
3.15。不可代理的 bean 类型
容器使用代理来提供某些功能。某些合法的 bean 类型不能被代理 容器:
- 没有无参数的非私有构造函数的类,
- 声明为 final 的类,
- 具有非静态最终方法的类具有公共、受保护或 默认可见性,
- 原始类型,
- 和数组类型。
如果注入点解析为 豆子:
- 需要客户端代理,或
- 具有关联的装饰器,或
- 具有绑定拦截器。
否则,容器会自动检测到问题,并处理 这是一个部署问题。
在Normal scopes and pseudo-scopes 部分的进一步说明:
所有普通范围必须显式声明@NormalScope,以向容器指示需要客户端代理。
鉴于@ApplicationScoped bean 的定义是@NormalScope,我需要一个非私有的无参数构造函数。那么我需要一个受保护的无参数构造函数来满足 CDI 规范吗?我尝试过使用受保护的无参数构造函数,它似乎可以工作,但我不明白 WELD 在这种情况下是如何工作的;它在什么情况下使用无参数构造函数?为什么这是 CDI 中的一项要求?
Weld 是否只使用无参数来创建代理,但在实际调用底层实现时,它使用基于注入的构造函数和参数?
【问题讨论】:
-
我不相信 Spring 有任何这样的限制。我会说它是一个比 Java EE 更好的 CDI 实现。
-
@duffymo 我不认为 Spring DI 实现了 CDI,即使它支持 JSR-330 和 JSR-250。如果你的意思是说它是更好的 DI 实现,我想我同意。
-
CDI 代表构造函数依赖注入吗?如果是,那么它肯定会。我认为最好是二传手注入。基于所有注释。
-
@duffymo 不,它代表Contexts and Dependency Injection for the Java EE platform,这是一个java EE规范。
-
我得看看它是什么意思。 Rod Johnson 是编写标准的委员会成员,所以我猜它接近 Spring。
标签: java jakarta-ee dependency-injection cdi weld