【发布时间】:2016-06-23 13:43:12
【问题描述】:
我有一些 bean(多种类型,CDI、@Stateless 和 @Singleton bean)。他们的一些字段应该从数据库值中注入。
public class MyBean {
@Inject
@DbConfigValue(MyConfig.HOST)
String host;
}
所以我添加了一个生产者使用的自定义@Qualifier (DbConfigValue)。生产者从数据库中读取并缓存配置值并将它们注入到 bean 中。
@Singleton
@Lock(LockType.READ)
public class Configuration {
@Produces
@Dependent
@DbConfigValue
public String getDbConfigValue(InjectionPoint point) {
// get key for the config-value from qualifier-annotation of the injected field
String key = point.getAnnotated().getAnnotation(DbConfigValue.class).value();
// i have read+cached database config values in @PostConstruct before
return cachedConfigValues.get(key);
}
}
这适用于初始注入/bean 构造。一些网络教程建议使用这种方法。
现在,我认为假设配置值(如果存储在 DB 中)可能会在运行时更改是合理的。因此,每当管理员更改数据库配置值时,我目前都会触发 CDI 事件。
问题:有没有办法将值重新注入到已经初始化的 bean 实例的字段中?还是注入总是只与实例创建有关?
例如我有……与此类似:
public class MyEventListener {
@Inject
BeanManager beanManager;
@Asynchronous
public void onDbConfigValueChangedEvent (@Observes(during = TransactionPhase.AFTER_SUCCESS) DbConfigValueChangedEvent event) {
try {
// could be filtered by custom qualifier:
Set<Bean<?>> beans = beanManager.getBeans(Object.class,new AnnotationLiteral<Any>() {});
for (Bean<?> bean : beans) {
Set<InjectionPoint> points = bean.getInjectionPoints();
// What now? javax.enterprise.inject.spi.Bean is the
// bean-representation only.
// Can I somehow resolve the actual bean-instances here?
// Then update Field via Reflection?
}
}
catch(Exception e){
// ...
}
}
}
我还考虑了DeltaSpike,它有一些注射控制方法。但是,我确实只找到了注入新 bean 实例的方法,甚至是使用 new-或 null-CreationalContexts (之后不再由 CDI 管理的 bean)
请注意:我知道我可以通过注入配置并显式获取每个请求的当前值来解决这个特定的用例,如下所示:
public class MyBean {
@Inject
Configuration config;
public void someMethod(){
String host = config.getConfig(MyConfig.HOST);
// ...
}
}
但是,我想知道一般问题:是否支持重新注入?或者如果没有,规范(CDI 或 Java EE)是否禁止它?
【问题讨论】:
标签: java jakarta-ee dependency-injection cdi weld