参考文档:https://www.jianshu.com/p/ef6f0c0de38f
1.相关概念
1.1 Spring IOC相关类
BeanFactory
BeanDefinitionRegistry
DefaultListableBeanFactory
BeanDefinition
AbstractBeanDefinition
RootBeanDefinition ChildBeanDefinition
ApplicationContext
1.2 Bean生命周期
- 实例化Bean对象
- 设置对象属性
- 检查Aware相关接口并设置相关依赖
- BeanPostProcessor前置处理
- 检查是否是InitializingBean
- 检查是否配置有自定义的init-method
- BeanPostProcessor后置处理
- 注册必要的Destruction相关回调接口
- 使用中
- 检查是否是DisposableBean
- 检查是否配置有自定义的destroy方法
1.3 Spring提供的Bean扩展
IOC容器负责管理容器中所有bean的生命周期,而在生命周期的不同阶段,Spring提供提供对应扩展点给到用户进行自定义处理。
| 生命周期阶段 | 类 | 说明 |
|---|---|---|
| 容器启动阶段 | BeanFactoryPostProcessor | BeanFactory的前置处理器,允许在容器实例化相应对象前,对注册到容器的BeanDefinition保存信息做额外的操作。 |
| 对象示例化阶段 | BeanPostProcessor | 处理容器内所有符合条件并且已经实例化后的对象 |
| 对象实例化完成后 | Aware接口 | 在对象实例化完成后将Aware接口中规定的依赖注入到当前实例中。 如ApplicationContextAware接口,实现了这个接口的类都可以获取到一个ApplicationContext对象。 当容器中每个对象的实例化过程走到BeanPostProcessor前置处理这一步时,容器会检测到之前注册到容器的ApplicationContextAwareProcessor,然后就会调用其postProcessBeforeInitialization()方法,检查并设置Aware相关依赖 |
1.4 事件监听机制
Java提供了实现事件监听的两个基础类:
- 自定义事件类型 java.util.EventObject
- 事件的监听器 java.util.EventListener
Spring的ApplicationContext内部的所有事件类型都继承自org.springframework.context.AppliationEvent,
所有监听器都实现org.springframework.context.ApplicationListener接口,并且以bean的形式注册在容器中,一旦在容器内发布ApplicationEvent及其子类型的事件,注册到容器的ApplicationListener就会对这些事件进行处理。
-
ApplicationEvent继承自EventObject,Spring提供了一些默认的实现,比如:
ContextClosedEvent表示容器在即将关闭时发布的事件类型
ContextRefreshedEvent表示容器在初始化或者刷新的时候发布的事件类型
-
容器内部使用ApplicationListener作为事件监听器接口定义,它继承自EventListener。
ApplicationContext容器在启动时,会自动识别并加载EventListener类型的bean,一旦容器内有事件发布,将通知这些注册到容器的EventListener。
ApplicationContext接口继承了ApplicationEventPublisher接口,该接口提供了void publishEvent(ApplicationEvent event)方法定义,不难看出,ApplicationContext容器担当的就是事件发布者的角色ApplicationContext将事件的发布以及监听器的管理工作委托给ApplicationEventMulticaster接口的实现类。在容器启动时,会检查容器内是否存在名为applicationEventMulticaster的ApplicationEventMulticaster对象实例。如果有就使用其提供的实现,没有就默认初始化一个SimpleApplicationEventMulticaster作为实现。
2.SpringBoot启动流程
启动流程都封装在SpringApplication.run方法中:
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
//1.通过SpringFactoriesLoader查找并加载所有的SpringApplicationRunListeners,通过调用
//starting()方法通知所有的SpringApplicationRunListeners:应用开始启动了
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
//2.创建并配置当前应用将要使用的Environment
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
configureIgnoreBeanInfo(environment);
//3.打印banner
Banner printedBanner = printBanner(environment);
//4.根据是否是web项目,来创建不同的ApplicationContext容器
context = createApplicationContext();
//5.创建一系列FailureAnalyzer
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//6.初始化ApplicationContext
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//7.调用ApplicationContext的refresh()方法,刷新容器
refreshContext(context);
//8.查找当前context中是否注册有CommandLineRunner和ApplicationRunner,如果有则遍历执行它们。
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, listeners, exceptionReporters, ex);
throw new IllegalStateException(ex);
}
listeners.running(context);
return context;
}