Подключитесь к иерархии источников свойств Spring Boot
Я знаю порядок по умолчанию источников свойств Spring: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html как я могу добавить свой собственный источник свойств с конкретный приоритет?
@PropertySource
недостаточно, так как добавляет новые свойства с очень низким приоритетом
1 ответ
Есть много способов сделать это; Я просто процитирую официальную документацию:
SpringApplication
имеетApplicationListener
с иApplicationContextInitializer
s, которые используются для применения настроек к контексту или среде. Spring Boot загружает ряд таких настроек для внутреннего использования изMETA-INF/spring.factories
, Существует несколько способов регистрации дополнительных:
- Программно для каждого приложения, вызвав
addListeners
а такжеaddInitializers
методы наSpringApplication
прежде чем запустить его.- Декларативно для каждого приложения путем установки
context.initializer.classes
или жеcontext.listener.classes
,- Декларативно для всех приложений, добавив
META-INF/spring.factories
и упаковку файла JAR, который все приложения используют в качестве библиотеки.
SpringApplication
отправляет некоторые специальныеApplicationEvents
к слушателям (даже некоторым до создания контекста), а затем регистрирует слушателей для событий, опубликованных ApplicationContext. Полный список см. В разделе 23.4 "События приложения и слушатели" в разделе "Функции Spring Boot".Также можно настроить
Environment
до обновления контекста приложения, используяEnvironmentPostProcessor
, Каждая реализация должна быть зарегистрирована вMETA-INF/spring.factories
:org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor
Мой путь всегда заключался в добавлении слушателя ApplicationEnvironmentPreparedEvent:
public class IntegrationTestBootstrapApplicationListener implements
ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 4;
public static final String PROPERTY_SOURCE_NAME = "integrationTestProps";
private int order = DEFAULT_ORDER;
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
if (!environment.getPropertySources().contains(PROPERTY_SOURCE_NAME)) {
Map<String, Object> properties = ...; // generate the values
// use whatever precedence you want - first, last, before, after
environment.getPropertySources().addLast(
new MapPropertySource(PROPERTY_SOURCE_NAME, properties));
}
}
}
Но вы можете так же легко использовать инициализатор:
public class IntegrationTestBootstrapApplicationListener implements
ApplicationContextInitializer<ConfigurableApplicationContext> {
private static final String PROPERTY_SOURCE_NAME = "integrationTestProps";
@Override
public void initialize(final ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
Map<String, Object> properties = ...; // generate the values
// use whatever precedence you want - first, last, before, after
environment.getPropertySources().addLast(
new MapPropertySource(PROPERTY_SOURCE_NAME, properties));
}
}