SpringBoot的启动流程
本文只简述了整体的启动流程,并不涉及到具体的代码实现
阶段一:SpringApplication 构造
- 记录primarysource
- 推断应用类型(1.非web程序2.基于servlet的程序3.基于reactive的程序)
- 设置 ApplicationContext 初始化器
- 设置监听器
- 推断主启动类(记录主启动类)
阶段二:执行 run 方法
-
构造一个StopWatch计时器,用来记录SpringBoot的启动时间 。
-
获取SpringApplicationRunListeners,名字取得不好,实际是事件发布器,用来在接下来的过程中发送一些事件
- 发布 application starting 事件(开始创建容器)
-
封装 main方法传来的args(DefaultApplicationArguments)
-
准备 Environment(prepareEnvironment方法)
-
ConfigurationPropertySources.attach(v) 对命名不规范的键进行处理
- 发布 application environment 已准备事件(会被下面这个监听器监听到)
-
通过 EnvironmentPostProcessorApplicationListener 进行 env 后处理,监听到application environment 事件后,去加载配置文件(spring.facories)中 EnvironmentPostProcessor的子实现类
用来对环境来源做一些扩展,也就是增加一些环境的来源
- application.properties,由 StandardConfigDataLocationResolver 解析
- spring.application.json
- 绑定 spring.main(配置文件)到 SpringApplication 对象属性中
- 打印 banner
- 创建容器,根据上面推断的容器类型创建对应的容器
- 准备容器
判断容器是否延迟加载、是的话增加一个用来延迟加载的bean工厂的后处理器( LazyInitializationBeanFactoryPostProcessor)
加载并注册BeanDenefine(从各种来源加载)- 发布 application Loaded
- refresh 容器
如果是web应用的话,这里最终会调用AbstractApplicationContext.refresh
- 创建BeanFactory,设置是否允许bean的覆盖、是否允许循环引用,加载BeanDenefine(xml文件)
- 容器的预准备工作(对beanFactory进行一些设置,比如设置context的类加载器)
- 实例化并调用beanfactory后处理器,实例化bean后处理器、
- 初始化国际化工具类MessageSource、事件广播器
- 初始化所有非延迟加载的单例bean等
- 发送容器已刷新的事件
发布 application started 事件
-
StopWatch计时器停止计时,日志打印总共启动的时间。
-
执行 runner(ApplicationRunner和CommandLineRunner),如果想在容器启动后就去执行一些操作,可以通过实现这两个Runner来完成
- 发布 application ready 事件
- 这其中有异常,发布 application failed 事件