因此,我尝试使用存储在cosul中的键/值覆盖application.properties中的值。我尝试了两件事。
1)使用Spring Cloud Consul Config。 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批注?
这是我当前的PostProcessor。
@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);
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;
}
}
}
}
}