通过 public 字段访问时 cdi bean 缺少值

cdi bean lack of value when accessed through public field

我有一个配置 class,我将其注入另一个 class。

配置class如下所示:

@RequestScoped
public class Configuration {

    @ConfigProperty(name = "VALUE")
    public String value;

    public String getValue() {
        return value;
    }
}

此配置注入到以下位置:

@ApplicationScoped
public class EndpointImpl implements Endpoint {

    private Configuration configuration;

    @Inject
    public EndpointImpl(Configuration configuration) {
        this.configuration = configuration;
        System.out.println("configuration.value=" + configuration.value);
        System.out.println("configuration.getValue()=" + configuration.getValue());
        System.out.println("configuration.value=" + configuration.value);
    }

通过构造函数后打印的日志:

configuration.value=null

configuration.getValue()=someValue

configuration.value=null

我使用以下类似代码添加了 postConstructor:

@PostConstruct
public void postConstruct(){
    System.out.println("configuration.value="+configuration.value);
    System.out.println("configuration.getValue()="+configuration.getValue());
    System.out.println("configuration.value="+configuration.value);
}

结果是一样的

只要通过 getter 方法检索值,一切正常。当我尝试通过 public 字段检索它时,它 returns 为空。我认为,当 CDI 完成构建 bean 的过程时,class 中的字段将被设置为适当的值。

为什么会这样?

这是预料之中的,因为您的 Configuration bean 是 @RequestScoped。请求范围是 so-called 正常范围 之一,每当你 @Inject 一个 normal-scoped bean 时,你总是会得到一个 so-called 客户端代理.

存在客户端代理以查找正确的 bean 实例并将方法调用转发给它。在这种情况下,它将查找 当前请求 .

的 bean 实例

因此,当您访问字段时,您是在客户端代理上访问它们,而不是在与当前请求相关的实例上。

无论何时注入 normal-scoped bean,都不要直接访问字段。始终调用方法。您可以直接访问 @Singleton@Dependent bean 上的字段,因为它们没有提供客户端代理。