Подключитесь к иерархии источников свойств Spring Boot

Я знаю порядок источников свойств Spring по умолчанию: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html как я могу добавить свой собственный источник свойств с определенным приоритетом ?

@PropertySource недостаточно, так как он добавляет новые свойства с очень низким приоритетом


person piotrek    schedule 26.08.2016    source источник


Ответы (1)


Есть много способов сделать это; Процитирую официальную документацию:

SpringApplication имеет ApplicationListener и ApplicationContextInitializer, которые используются для применения настроек к контексту или среде. 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));
    }
}
person Miloš Milivojević    schedule 26.08.2016
comment
Можете ли вы описать make spring для обнаружения вашего инициализатора? Где используется этот класс? - person Federico Piazza; 15.03.2017
comment
В цитируемом тексте уже есть описание, подробности см. в маркированном списке. - person Miloš Milivojević; 15.03.2017
comment
Добавление в META-INF/spring.factories у меня не сработало - person supertonsky; 23.05.2018
comment
Маловероятно, что эта функция не работает, так как вся автонастройка Spring Boot опирается на spring.factories, возможно, вы где-то ошиблись :) - person Miloš Milivojević; 24.05.2018