gpt4 book ai didi

java - 使用 EnvironmentPostProcessor 的 Spring Boot : Attempting to override application. 属性

转载 作者:行者123 更新时间:2023-11-30 12:02:14 29 4
gpt4 key购买 nike

所以我尝试使用存储在 Cosul 中的键/值来覆盖 application.properties 中的值。我尝试了两件事。

1) 使用 Spring Cloud Consul 配置。 https://cloud.spring.io/spring-cloud-consul/reference/html/#spring-cloud-consul-config

如果我没有在我的 application.properties 中定义相同的键,这会起作用。如果它是在 application.properties 中定义的,则属性文件中的值将用于所有 @Value 注释解析。这与我想要的相反。

2) 由于以上方法无效,我继续创建自定义 EnvironmentPostProcessor。我首先尝试构建一个 MapPropertySource 并使用了 environment.getPropertySources().addAfter(..)。这与上面的结果相同。然后,我尝试遍历所有属性源,找到名称包含“applicationConfig: [classpath:/application”的属性源,如果存在则设置属性值或设置新的属性值。此外,我将 MapPropertySource 添加到“applicationConfig: [classpath:/application”属性源所在的同一个 EnumerableCompositePropertySource。

无论采用哪种方法,结果始终相同。如果键存在于 application.properties 中,则使用该值。

什么给了?我实际上是在覆盖属性源中的值,并且在 PostProcessor 完成它的工作之前我可以在调试器中看到这些值。 application.properties 值如何仍然到达@Value 注释?

这是我当前的后处理器。

@Order(Ordered.LOWEST_PRECEDENCE)
public class ConsulPropertyPostProcessor implements EnvironmentPostProcessor {


private static final String PROPERTY_SOURCE_NAME = "applicationConfigurationProperties";

@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
PropertySource<?> system = environment.getPropertySources().get(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);

ConsulKVService consulKVService = new ConsulKVServiceImpl().instantiateConsulKVServiceImpl((String)system.getProperty("CONSUL_HOST"), (String)system.getProperty("CONSUL_TOKEN"));
Map<String, Object> map = consulKVService.getConsulKeysAndValuesByPrefix((String)system.getProperty("CONSUL_PREFIX"));


addOrReplace(environment.getPropertySources(), map);
}

private void addOrReplace(MutablePropertySources propertySources, Map<String, Object> map) {
MapPropertySource target = new MapPropertySource("applicationConfig: [consulKVs]", map);
if (propertySources.contains(PROPERTY_SOURCE_NAME)) {
PropertySource<?> applicationConfigurationPropertySources = propertySources.get(PROPERTY_SOURCE_NAME);

for(EnumerableCompositePropertySource applicationPropertySource : (ArrayList<EnumerableCompositePropertySource>)applicationConfigurationPropertySources.getSource()){
if(applicationPropertySource.getName() != null
&& applicationPropertySource.getName().contains("applicationConfig: [profile=")) {

for(PropertySource singleApplicationPropertySource : applicationPropertySource.getSource()){
if(singleApplicationPropertySource.getName().contains("applicationConfig: [classpath:/application")){

for (String key : map.keySet()) {
if(map.get(key) != null) {
if (singleApplicationPropertySource.containsProperty(key)) {
((Properties) singleApplicationPropertySource.getSource())
.setProperty(key, (String) map.get(key));
} else {
((Properties) singleApplicationPropertySource.getSource()).put(key, (String) map.get(key));
}
}
}
break;
}
}

applicationPropertySource.add(target);

break;


}
}

}

}
}

提前谢谢大家。

编辑:尝试覆盖 ApplicationListener 类的 onApplicationEvent 方法,结果与上面相同。这是代码。

@Log4j
public class ConsulProperties implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {

static ConfigurableEnvironment configurableEnvironment;
private static final String PROPERTY_SOURCE_NAME = "applicationConfigurationProperties";

public static ConfigurableEnvironment getConfigurableEnvironment() {
return configurableEnvironment;
}

@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
log.info("Received ApplicationEnvironmentPreparedEvent...");
ConfigurableEnvironment environment = event.getEnvironment();
configurableEnvironment = environment;
Properties props = new Properties();

ConsulKVService consulKVService = new ConsulKVServiceImpl()
.instantiateConsulKVServiceImpl((String) configurableEnvironment.getProperty("CONSUL_HOST"),
(String) configurableEnvironment.getProperty("CONSUL_TOKEN"));
Map<String, Object> map = consulKVService.getConsulKeysAndValuesByPrefix((String) configurableEnvironment.getProperty("CONSUL_PREFIX"));
while(map.values().remove(null));
addOrReplace(environment.getPropertySources(), map);
}


private void addOrReplace(MutablePropertySources propertySources, Map<String, Object> map) {
MapPropertySource target = new MapPropertySource("applicationConfig: [consulKVs]", map);
if (propertySources.contains(PROPERTY_SOURCE_NAME)) {
PropertySource<?> applicationConfigurationPropertySources = propertySources.get(PROPERTY_SOURCE_NAME);

for(EnumerableCompositePropertySource applicationPropertySource : (ArrayList<EnumerableCompositePropertySource>)applicationConfigurationPropertySources.getSource()){
if(applicationPropertySource.getName() != null
&& applicationPropertySource.getName().contains("applicationConfig: [profile=")) {

for(PropertySource singleApplicationPropertySource : applicationPropertySource.getSource()){
if(singleApplicationPropertySource.getName().contains("applicationConfig: [classpath:/application")){

for (String key : map.keySet()) {
if (singleApplicationPropertySource.containsProperty(key)) {
((Properties) singleApplicationPropertySource.getSource())
.setProperty(key, (String) map.get(key));
} else {
((Properties) singleApplicationPropertySource.getSource()).put(key,
map.get(key));
}
}


applicationPropertySource.add(target);

Properties properties = new Properties();
properties.putAll(map);
propertySources.addLast(new PropertiesPropertySource("consulKVs", properties));

break;
}
}


break;


}
}
}
}
}

最佳答案

您使用以下代码添加新属性源的代码存在问题。请注意,当您调用“addLast”时,通过此方法添加的属性源具有最低的优先级,并且永远不会更新已经可用的属性。

propertySources.addLast(new PropertiesPropertySource("consulKVs", properties));

您可以使用“addFirst”来添加属性源,而不是上面的代码,它应该具有最高优先级,如下面的代码所示。还有一些其他方法,如“addAfter”和“addBefore”也可用,您可以探索以在确切位置添加属性源。在任何情况下,“addFirst”将优先于所有其他方式,因此我认为您可以使用“addFirst”来更新属性源。

propertySources.addFirst(new PropertiesPropertySource("consulKVs", properties));

我已经使用 ApplicationEnvironmentPreparedEvent 测试了这个场景,它工作正常。希望它能解决您的问题。

关于java - 使用 EnvironmentPostProcessor 的 Spring Boot : Attempting to override application. 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58750735/

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