通过 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 上的字段,因为它们没有提供客户端代理。
我有一个配置 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 上的字段,因为它们没有提供客户端代理。