CDI 对象不能使用注入的构造函数进行代理

2022-09-03 14:46:18

当尝试将参数注入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)

但是,我在类上确实有一个可注入的构造函数:

@Inject
public Config(ConfigLocator configLocator) {
    defaultConfigPath = configLocator.getPath();
    doStuff();
}

使用默认构造函数,变量注入和后构造方法,这一切都可以正常工作,但在这种情况下,我更喜欢构造函数注入。

任何想法这里出了什么问题?


答案 1

我们解决了将类拆分为接口和实现的类似问题。在你的情况下,像这样:

public interface Config
{
  // API here
}

@ApplicationScoped @Priority(0)
public class ConfigImpl implements Config
{
  @Inject
  public ConfigImpl(ConfigLocator configLocator) { ... }

  // API implementation here
}

答案 2

这个例子可能会帮助你:

@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() {
    }

}

您需要在 bean @ApplicationScoped中有一个公共非 args 构造函数。

注意:此类的 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].

这样做的可能原因是,需要一个不依赖的作用域 Bean 为 CDI 提供一个公共的 no-args 构造函数,以便它可以在运行时获取所需的代理 Bean。


推荐