Springboot框架中提供了两种类型的应用上下文ApplicationContext,分别为:
- AnnotationConfigServletWebServerApplicationContext。
- AnnotationConfigReactiveWebServerApplicationContext。
public class SpringApplication {public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.bootstrapRegistryInitializers = getBootstrapRegistryInitializersFromSpringFactories();//获取接口ApplicationContextInitializer的所有实现类setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = deduceMainApplicationClass();}public ConfigurableApplicationContext run(String... args) {...SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting(bootstrapContext, this.mainApplicationClass);ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);//实例化ApplicationContext实例context = createApplicationContext();prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);refreshContext(context);return context;}private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments, Banner printedBanner) {//应用上下文持有Environmentcontext.setEnvironment(environment);postProcessApplicationContext(context);// ApplicationContextInitializer接口核心方法之initialize方法applyInitializers(context);// 监听器触发 ApplicationContextInitializedEvent类型的事件listeners.contextPrepared(context);...}}
2.ApplicationContextInitializer
这是一个跟应用上下文相关的回调接口,其目的是优先为应用上下文ApplicationContext做一些初始化功能。比较典型的是web应用中通过回调接口为ApplicationContext做一些计划性的初始化工作。例如为ApplicationContext的Environment属性注册property sources or activating profiles等。
@FunctionalInterface
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {void initialize(C applicationContext);
}
SpringBoot框架通过spring.factories文件默认提供了如下子类:
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer,
com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer
这些子类的加载时机为类SpringApplication的构造方法。
public class SpringApplication {protected void applyInitializers(ConfigurableApplicationContext context) {for (ApplicationContextInitializer initializer : getInitializers()) {Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),ApplicationContextInitializer.class);initializer.initialize(context);}}
}
3.ApplicationContextInitializedEvent
SpringBoot框架内部并没有内置监听器ApplicationListener处理该类型的事件。
public class ApplicationContextInitializedEvent extends SpringApplicationEvent {private final ConfigurableApplicationContext context;public ApplicationContextInitializedEvent(SpringApplication application, String[] args,ConfigurableApplicationContext context) {super(application, args);this.context = context;}public ConfigurableApplicationContext getApplicationContext() {return this.context;}}
用户可以实现支持该事件类型的监听器ApplicationListener。如上所示监听器处理该事件时是基于SpringApplication类、运行参数或者应用参数、ConfigurableApplicationContext。