Введение в ApplicationContextInitializer
роль вConfigurableApplicationContext
ТипApplicationContext
.refresh
Перед операцией позвольте намConfiurableApplicationContext
Расширения для улучшения обработки.
Деловая сцена
В реальном процессе разработки контекст приложения необходимо программно инициализировать в веб-приложении. Например, регистрация источника свойства(bootstrap/application properties sources)
; Кодированные динамические активации отличаютсяprofile
вести перепискуenvironment
Еще один недавний проект, в соответствии с различными средамиLinux/Windows
для загрузки различных параметров SDK.
настроитьCondition
выполнить
Из-за чрезвычайно большого количества элементов конфигурации, путем измененияConfigurationProperties
Настроить на Bean@Conditional
public class LinuxCondition implements Condition{
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String property = context.getEnvironment().getProperty("os.name");
...
return property.contains("linux");
}
}
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional({LinuxCondition.class})
public @interface ConditionOnLinux {}
Поскольку классы конфигурации, разработанные SDK, извлекаются слишком часто, а разделение нецелесообразно, от этого метода отказались, не уничтожив культурные реликвии.
Пользовательская реализация ApplicationContextInitializer
Загружайте по контекстуresource
Каталоги, файлы конфигурации для разных сред
public class SelectApplicationContextInitializer implements ApplicationContextInitializer {
@Override
public void initialize(ConfigurableApplicationContext context) {
ConfigurableEnvironment env = context.getEnvironment();
MutablePropertySources mps = env.getPropertySources();
String property = env.getProperty("os.name");
if (property.contains("Mac OS X")) {
mps.addLast(new ResourcePropertySource(new ClassPathResource("linux.properties")));
} else {
mps.addLast(new ResourcePropertySource(new ClassPathResource("window.properties")));
}
}
}
Проблема: инициализация выполняется дважды
Извлеките соответствующие функции вstarter
, работает на синглтонеSpring Boot
проект, если добавленSpring Cloud Context
выполнит приведенный выше код дважды
SpringApplication.run
- Чтобы выяснить настоящего виновника, под методом запуска SpringApplication была поставлена точка останова.
BootstrapApplicationListener
следовал всю дорогуBootstrapApplicationListener.bootstrapServiceContext
метод.
Давайте посмотримbootstrapServiceContext
метод,
SpringApplicationBuilder builder = (new SpringApplicationBuilder(new Class[0])).profiles(environment.getActiveProfiles()).bannerMode(Mode.OFF).environment(bootstrapEnvironment).registerShutdownHook(false).logStartupInfo(false).web(WebApplicationType.NONE);
SpringApplication builderApplication = builder.application();
if (builderApplication.getMainApplicationClass() == null) {
builder.main(application.getMainApplicationClass());
}
if (environment.getPropertySources().contains("refreshArgs")) {
builderApplication.setListeners(this.filterListeners(builderApplication.getListeners()));
}
builder.sources(new Class[]{BootstrapImportSelectorConfiguration.class});
ConfigurableApplicationContext context = builder.run(new String[0]);
context.setId("bootstrap");
предупреждение правды
BootstrapApplicationListener
в использованииSpringApplicationBuilder
сделал перезагрузку, хотя это былоRun
Дважды но в первый раз не запускал контейнер и т.д., так и появилосьBean
загрузить дважды или запустить контейнерTomcat
И другие конфликты портов.