springboot的主要对象:
- SpringApplicationRunListeners :springboot 的事件监听器的对象列表,主要是监听整个spring boot的生命周期,所以springboot初始化的首要目的就是获取当前的所有的监听器,这种监听器是不能通过bean来实现的,因为当前的spring的factory尚未创建,所以只能在配置文件里面。再者当前的监听器是需要监听这个生命周期的,所以首要创建的对象就是这个。
- ApplicationArguments 应用的启动参数对象,这个主要是对命令行的启动参数进行了一层的封装,对命令的所有操作应该都封装在里面了。
- ConfigurableEnvironment 这个是为spring 上下文准备的环境对象,springboot主要做的是通过命令参数,构建一个命令的配置源。
- ApplicationContextInitializer是Spring框架原有的东西,这个类的主要作用就是在ConfigurableApplicationContext类型(或者子类型)的ApplicationContext做refresh之前,允许我们对ConfiurableApplicationContext的实例做进一步的设置和处理。
重要步骤的理解
准备上下文:
为啥要有个准备上下文的步骤呢?因为在刷新spring应用之前,可以提前做很多准备。
- 给机会开发者修改context。比如监听器和ApplicationContextInitializer等钩子接口在这时候回调。
- 注册一些springboot特定的bean
- 创建beanloader加载当前启动类的bean定义等
- 加载完再调用监听器给监听器机会修改context
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
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// Load the sources,加载bean定义的一些信息
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[0]));
//加载完回调钩子函数
listeners.contextLoaded(context);
}
protected ConfigurableApplicationContext createApplicationContext() {
//配置的contextClass创建应用上下文,是null,走策略模式,主要是为了拓展
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
如上图通过反射去实例化spring上下文容器。