Поэтому я пытаюсь использовать ключ / значения, хранящиеся в 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 в тот же EnumerableCompositePropertySource, в котором находится источник свойства applicationConfig: [classpath: / application ».
При любом подходе результат всегда один и тот же. Если ключ существует в 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;
}
}
}
}
}
Заранее спасибо всем.
РЕДАКТИРОВАТЬ: Пробовалпереопределение метода onApplicationEvent класса ApplicationListener с тем же результатом, что и выше. Вот этот код.
@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;
}
}
}
}
}