前面已经对Spring Boot启动过程进行过源码分析,对于代表容器上下文的关键字段ApplicationContext只是一笔带过。实际上,它的生命周期才应该是重点关注的。
Spring Boot使用的ApplicationContext
分两种场景,常规应用和Web应用使用的上下文类型不一样:
- 常规应用:org.springframework.context.annotation.AnnotationConfigApplicationContext
- Web应用:org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext
从类型层次来看的话:
AnnotationConfigApplicationContext(由Spring Context定义)
AnnotationConfigEmbeddedWebApplicationContext(由Spring Boot定义)
从类图中可以发现,它们都有共同的父类GenericApplicationContext,在这地方出现了分支。
再谈ApplicationContextInitializer
在创建好了ApplicationContext之后,会进行prepare操作:
private void prepareContext(ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
context.setEnvironment(environment);
postProcessApplicationContext(context);
applyInitializers(context);
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
context.getBeanFactory().registerSingleton("springApplicationArguments",
applicationArguments);
if (printedBanner != null) {
context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
}
// Load the sources
Set<Object> sources = getSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[sources.size()]));
listeners.contextLoaded(context);
}
这里面比较重要的就是调用注册的ApplicationContextInitializer实现。