gpt4 book ai didi

java - 带有 CDI 的 DeltaSpike 自定义 ConfigSource

转载 作者:行者123 更新时间:2023-12-02 08:46:17 24 4
gpt4 key购买 nike

我正在尝试定义自定义 DeltaSpike ConfigSource。自定义配置源将具有最高优先级,并检查数据库中的配置参数。

我有一个 ConfigParameter 实体,它只有一个键和一个值。

@Entity
@Cacheable
public class ConfigParameter ... {

private String key;
private String value;

}

我有一个可以查找所有配置参数的@Dependent DAO。

我现在想做的是定义一个自定义的 ConfigSource,它能够从数据库获取配置参数。因此,我想将我的 DAO 注入(inject)到 ConfigSource 中。所以基本上是这样的

@ApplicationScoped
public class DatabaseConfigSource implements ConfigSource {

@Inject
private ConfigParameterDao configParameterDao;

....
}

但是,当通过 META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource 注册 ConfigSource 时,该类将被实例化,并且 CDI 将无法工作。

在这种情况下有什么方法可以让 CDI 工作吗?

提前致谢,如果您需要更多信息,请告诉我。

最佳答案

主要问题是,当 BeanManager 尚不可用时,ConfigSource 会很早就被实例化。即使 JNDI 查找在那个时间点也不起作用。因此,我需要延迟注入(inject)/查找。

我现在所做的是将静态 boolean 值添加到我手动设置的配置源中。我们有一个 InitializerService 来确保系统设置正确。在初始化过程结束时,我调用 allowInitialization() 来告诉配置源,该 bean 现在可以注入(inject)了。下次询问 ConfigSource 时,它​​将能够使用 BeanProvider.injectFields 注入(inject) bean。

public class DatabaseConfigSource implements ConfigSource {

private static boolean allowInit;

@Inject
private ConfigParameterProvider configParameterProvider;

@Override
public int getOrdinal() {
return 500;
}

@Override
public String getPropertyValue(String key) {
initIfNecessary();

if (configParameterProvider == null) {
return null;
}

return configParameterProvider.getProperty(key);
}

public static void allowInitialization() {
allowInit = true;
}

private void initIfNecessary() {
if (allowInit) {
BeanProvider.injectFields(this);
}
}

}

我有一个请求范围的 bean,它保存所有配置变量以进行类型安全访问。

@RequestScoped
public class Configuration {

@Inject
@ConfigProperty(name = "myProperty")
private String myProperty;

@Inject
@ConfigProperty(name = "myProperty2")
private String myProperty2;

....

}

当在不同的bean中注入(inject)Configuration类时,每个ConfigProperty都会被解析。由于我的自定义 DatabaseConfigSource 具有最高序数 (500),因此它将首先用于属性解析。如果没有找到该属性,它将把解析委托(delegate)给下一个 ConfigSource。

对于每个 ConfigProperty,都会调用 DatabaseConfigSource 中的 getPropertyValue 函数。由于我不想从数据库中检索每个配置属性的参数,因此我将配置属性解析移至请求范围的 bean。

@RequestScoped
public class ConfigParameterProvider {

@Inject
private ConfigParameterDao configParameterDao;

private Map<String, String> configParameters = new HashMap<>();

@PostConstruct
public void init() {
List<ConfigParameter> configParams = configParameterDao.findAll();
configParameters = configParams.stream()
.collect(toMap(ConfigParameter::getId, ConfigParameter::getValue));
}

public String getProperty(String key) {
return configParameters.get(key);
}

}

我肯定可以将请求范围的 ConfigParameterProvider 更改为 ApplicationScoped。但是,我们有一个 Multi-Tenancy 设置,并且需要根据请求解析参数。

正如您所看到的,这有点 hacky,因为我们需要显式地告诉 ConfigSource,何时允许正确实例化它(注入(inject) bean)。

我更喜欢 DeltaSpike 的标准化解决方案,以便在 ConfigSource 中使用 CDI。如果您对如何正确实现这一点有任何想法,请告诉我。

关于java - 带有 CDI 的 DeltaSpike 自定义 ConfigSource,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37283009/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com