背景
每天都在使用spring boot,不了解基础的启动流程是真的说不过去。本wiki将进行启动流程阐述。
启动流程
- 推断应用的类型,是普通的类型还是web类型
- 查找并且加载initiallizers
- 查找并且加载listeners
- 推断并设置main方法的定义类,找到运行的主类
run时序图
DemoApplication SpringApplication StopWatch System SpringFact BeanUtils SpringApplicat Binder SpringApplicati SpringBootExc ConfigurableApp AbstractAppli ListableBeanFactory ApplicationRunner run(传入自己的class) 构造一个 推断web类型、 推断main的所 在类、初始化上下 文 run 创建并时间监控 setProperty(设置必要的环境变量) loadFactoryNames(获取META-INF/spring.factories的类名,本次只关心SpringApplicationRunListener) instantiateClass(实例化拿到的类) starting(开始监听) 配置web环境和profile等参数(以及客户化环境) SpringApplication和web环境绑定 通知web环境准备完毕 打印banner图 创建指定的上下文org.springframework.context.annotation.AnnotationConfigApplicationContext 创建异常报告者(获取META-INF/spring.factories的类名,本次只关心SpringBootExceptionReporter) 准备上下文 通知准备上下文完成 refresh(刷新过程是各种资源的整合过程) 完成时间监控 started(通知开始完毕) getBeansOfType(获取所有的Runner) run(调起回调) DemoApplication SpringApplication StopWatch System SpringFact BeanUtils SpringApplicat Binder SpringApplicati SpringBootExc ConfigurableApp AbstractAppli ListableBeanFactory ApplicationRunner
通过listener的视角观察启动过程
创建一个spring boot的Hello项目,并且添加一个listener
添加了断点以后,运行,看看效果
这里可以清楚的看到是进行同步传消息,而且把SpringApplication对象也回调回来了。
initializers一共有7个,listeners共12个(最后一个是我们注册的)。
initializers来源于(spring模仿的jdk的spi技术):
listeners来源于(spring模仿的jdk的spi技术)
listener一共回调了n个消息,依次为:
- ApplicationStartingEvent
- ApplicationEnvironmentPreparedEvent
- ApplicationContextInitializedEvent
- ApplicationPreparedEvent
- ContextRefreshedEvent
- ApplicationStartedEvent
- ApplicationReadyEvent
- ContextClosedEvent
通过Configuration的视角
以Mybatis的启动器为例来进行阐述
下断点进行跟踪,最终会进行sqlSessionFactory的bean创建
bean的创建必然是通过spring-beans模块实现的,如下图
beanName是来自于spring.factories中的EnableAutoConfiguration配置,实现类为(在spring-boot-autoconfigure包中)
评价
本wiki都是用的上层概念来进行推测,之后需要深入到每个模块中去,才可以更好的了解其中的过程。