SpringBoot运行流程源码分析:run方法流程及监听器( 四 )


-application :类 型为 SpringApplication, 是当前运行的 SpringApplication 实例 。
-args:启动程序时的命令参数 。
-initialMulticaster:类 型为 SimpleApplicationEventMulticaster,事件广播器 。
Spring Boot 完成基本的初始化之后 , 会遍历 SpringApplication 的所有 ApplicationListener实 例,并 将 它 们 与 SimpleApplicationEventMulticaster 进 行 关 联,方 便SimpleApplicationEvent-Multicaster 后续将事件传递给所有的监听器 。
EventPublishingRunListener 针对不同的事件提供了不同的处理方法 , 但它们的处理流程基本相同 。
SpringBoot运行流程源码分析:run方法流程及监听器文章插图
下面我们根据图 4-3 所示的流程图梳理一下 整个事件的流程 。
.程序启动到某个步骤后 , 调用 EventPublishingRunListener 的某个方法 。
EventPublishingRunListener 的具体方法将 application 参数和 args 参数封装到对应的事件中 。 这里的事件均为 SpringApplicationEvent 的实现类 。
.通过成员变量 initialMulticaster 的 multicastEvent 方法对事件进行广播 , 或通过该方法的ConfigurableApplicationContext 参数的 publishEvent 方法来对事件进行发布 。
.对应的 ApplicationListener 被触发 , 执行相应的业务逻辑 。
下面是 starting 方法的源代码 , 可对照上述流程进行理解 。 该方法其他功能类似 , 代码不再展示 。
public void starting() {this. initialMulticaster . multicastEvent(new ApplicationStartingEvent (this. application, this.args));}在上述源代码中你是否发现-个问题 , 某些方法是通过 initialMulticaster 的 multicastEvent进行事件的广播 , 某些方法是通过 context 参数的 publishEvent 方法来进行发布的 。 这是为什么呢?在解决这个疑问之前 , 我们先看一个比较特殊的方法 contextL oaded 的源代码 。
public void contextLoaded( ConfigurableApplicationContext context) {//遍历 application 中的所有监听器实现类for (ApplicationL istener listener : this . application. getL isteners()) {//如果为 Appl icationContextAware,则将上:下文信息设置到该监听器内if (listener instanceof Applicat ionContextAware) {((ApplicationContextAware) listener). setApplicationContext( context);//将 application 中的监听器实现类全部添加到上下文中context . addApplicationL istener(listener);// / "播事件 Appl icationPreparedEventthis. initialMulticaster . multicastEvent (new ApplicationPreparedEvent(this.application, this.args, context));}contextLoaded 方法在发布事件之前做了两件事:第一 , 遍历 application 的所有监听器实现类 , 如果该实现类还实现了 ApplicationContextAware 接口 , 则将上下文信息设置到该监听器内;第二 , 将 application 中的监听器实现类全部添加到上下文中 。 最后一步才是调用事件广播 。
也正是这个方法形成了不同事件广播形式的分水岭 , 在此方法之前执行的事件广播都是通过multicastEvent 来进行的 , 而该方法之后的方法则均采用 publishEvent 来执行 。 这是因为只有到了 contextL oaded 方法之后 , 上下文才算初始化完成 , 才可通过它的 publishEvent 方法来进行事件的发布 。
自定义 SpringApplicationRunListener
上面我们一起学习了 SpringApplicationRunListener 的基本功能及实现类的源代码 , 现在我们自定义-个 SpringApplicationRunListener 的实现类 。 通过在该实现类中回调方法来处理自己的业务逻辑 。