Ste*_*ote 12 java dependency-injection cdi weld
尝试将参数注入CDI bean(ApplicationScoped)的构造函数时,遇到以下问题:
Caused by: org.jboss.weld.exceptions.UnproxyableResolutionException: WELD-001435: Normal scoped bean class xx.Config is not proxyable because it has no no-args constructor - Managed Bean [class xx.Config] with qualifiers [@Default @Named @Any].
at org.jboss.weld.bean.proxy.DefaultProxyInstantiator.validateNoargConstructor(DefaultProxyInstantiator.java:50)
at org.jboss.weld.util.Proxies.getUnproxyableClassException(Proxies.java:217)
at org.jboss.weld.util.Proxies.getUnproxyableTypeException(Proxies.java:178)
Run Code Online (Sandbox Code Playgroud)
但是,我在类上确实有一个可注入的构造函数:
@Inject
public Config(ConfigLocator configLocator) {
defaultConfigPath = configLocator.getPath();
doStuff();
}
Run Code Online (Sandbox Code Playgroud)
使用默认构造函数,变量注入和postconstruct方法,这些都可以正常工作,但是在这种情况下,我更喜欢使用构造函数注入。
有什么想法怎么了?
我们解决了将类拆分为接口和实现的类似问题。在您的情况下,如下所示:
public interface Config
{
// API here
}
@ApplicationScoped @Priority(0)
public class ConfigImpl implements Config
{
@Inject
public ConfigImpl(ConfigLocator configLocator) { ... }
// API implementation here
}
Run Code Online (Sandbox Code Playgroud)
这个例子可能会帮助你:
@ApplicationScoped
public class Config {
private String defaultConfigPath;
@Inject
public Config(ConfigLocator configLocator) {
this.defaultConfigPath = configLocator.getPath();
doStuff();
}
// create a no-args constructor which is required for any scoped bean.
public Config() {
}
}
Run Code Online (Sandbox Code Playgroud)
bean中需要有一个公共的无参数构造函数@ApplicationScoped
。
注意:此类的 bean 将仅创建一次,并在应用程序的整个生命周期中维护。该 bean 将在所有托管 bean 之间共享。@ApplicationScoped beans本质上是单例的。
提到的问题:
Caused by: org.jboss.weld.exceptions.UnproxyableResolutionException: WELD-001435: Normal scoped bean class xx.Config is not proxyable because it has no no-args constructor - Managed Bean [class xx.Config] with qualifiers [@Default @Named @Any].
Run Code Online (Sandbox Code Playgroud)
可能的原因是,需要一个非依赖作用域 bean 来为 CDI 提供一个公共的无参数构造函数,以便它可以在运行时获取所需的代理 bean。
实现需要非私有、无参数构造函数来创建托管 bean 的代理。您不会因为存在非私有、无参数构造函数而失去注入构造函数的功能。
容器使用代理来允许拦截、修饰等操作,并在取消引用 bean 时检索正确的上下文实例。它还需要允许 bean 之间的循环注入。