本文已参与「新人创作礼」活动,一起开启掘金创作之路。
执行 run 方法
SpringApplication 实例创建完毕了, 现在需要执行 run 方法.
进入 run 方法,run 方法内部就是 SpringBoot 项目启动的主要逻辑了,源码如下:
1.启动计时器
首先是启动了一个计时器 StopWatch , 用来统计应用启动耗时, 最后在启动结束后输出.
2.设置 headless 属性
源码中configureHeadlessProperty()方法是当前系统属性中不存在java.awt.headless属性时, 设置其为 true. 没太懂这个, 反正意思是设置为 true 时, 运行在服务器端, 在没有显示器器和鼠标键盘的模式下照样可以工作.
3.获取并启动监听器
先来看看获取监听器, 进入getRunListeners()方法:
在 getRunListeners 方法里, 又看到了熟悉的 getSpringFactoriesInstances 方法, 这次它用来获取并实例化key = SpringApplicationRunListener的对象.
这里只有一个配置
所以会调用EventPublishingRunListener的构造方法如下:
这里获取到了 application 的 所有 listener, 通过 debug 可知, 这里的 listener 都是在 前一步的 创建SpringApplication 实例时的 3.加载所有的监听器 中加载的. 总共 12 个.
EventPublishingRunListener 是 SpringBoot 中唯一一个实现了 SpringApplicationRunListener 接口的监听器, 其主要作用是, 根据 SpringBoot 启动过程的不同阶段发布对应的事件, 进行对应阶段的相关操作.
getRunListeners 方法返回的是 SpringApplicationRunListeners对象, 该对象内部使用 List 存放所有实例化的 SpringApplicationRunListener.
然后就是调用 SpringApplicationRunListeners 的starting()方法,
循环调用SpringApplicationRunListener接口实现的 starting() 方法, EventPublishingRunListener 是其唯一实现类, 所以这里就是调用 EventPublishingRunListener 的 starting() 方法.
调用了 initialMulticaster 对象的multicastEvent方法, 并且传入了ApplicationStartingEvent对象作为入参.
initialMulticaster 是类SimpleApplicationEventMulticaster的实例. 是事件的广播器. 这里用到了观察者模式.
直接来看 initialMulticaster 的 multicastEvent 方法:
调用了resolveDefaultEventType()方法, 从字面意思可以得知, 这是在解析容器启动的当前事件类型.
ApplicationStartingEvent 类的父类是 抽象类 SpringApplicationEvent, 而 SpringApplicationEvent 的父类是 ApplicationEvent.
SpringApplicationEvent 有 7 个子类, 分别对应了容器启动的状态.
进入multicastEvent()方法如下:
根据当前的事件类型, 获取监听了当前 event 事件的监听器 listener, 不监听当前事件的监听器会被排除, 然后判断是否设置了线程池, 有设置, 则使用线程池去执行 listener 方法(异步执行), 否则, 则是使用当前线程去执行(同步执行).
invokeListener() 方法最后调用的是 listener 的 onApplicationEvent() 方法.
4.设置应用程序参数
这一步实例化了 DefaultApplicationArguments 对象, 然后将 args 参数设置给该对象, 其实就是对输出的 args 参数进行了一层包装.
args 参数, 就是在主启动类中设置的 args 参数.