springboot启动后执行方法_源码解析(三):SpringBoot是怎么执行监听器的?事件驱动思想...

点击右上角“关注”,跟我一起深入分析、学习SpringBoot最新版本源码!

系列文章:

源码解析(一):SpringBoot是怎么启动的?(基于最新版2.2.0)

源码解析(二):SpringBoot是如何一步步加载监听器的?

上篇我们主要讲述了SpringBoot-2.2.0.RELEASE版本在启动过程中是如何一步步的从META-INF/spring.factories文件中加载到所有的监听器并通过反射实例化成监听器示例。

全篇讲解的就一句代码:

77c73229e3cc84501d55c21eba8884de.png

今天我们继续分析下一句代码:

27f8a07a5d68b91ff9114a796a7c58da.png

当SpringBoot成功获取到所有已配置的监听器之后是如何启动这些监听器的呢?

让我们一起进入starting()这个方法的源码中去,点击starting方法进入如下源码:

7149daa5040e7453ffd7f7cd539b499f.png

starting方法就是循环的执行每一个监听器的方法,点击listener.starting()方法进入实现类EventPublishingRunListener的starting方法:

c9364ceab495152e7ae3c9dc2fe443be.png

EventPublishingRunListener

EventPublishingRunListener这个类是什么时候初始化的呢?

肯定是在我们要分析的

listeners.starting()

方法之前对吧,否则这个starting方法是无法执行的。

我们先看看这个类的继承关系、成员变量以及构造方法:

d8091678f0b50f17c0ae95f38788217b.png

然后我们需要找到初始化这个类的时机,在构造方法里打好断点,启动项目,从启动类开始执行进来。

如果大家看了上篇源码解析(二):SpringBoot是如何一步步加载监听器的?,一步步debug就会找到这个EventPublishingRunListener类,通过反射的方式获取其实例:

38dc79aa0a00af374e29afd313d3b2ce.png

然后通过构造方法设置好这个类的每一个参数,从上图我们可以看到SpringApplication启动类的详细信息。

其中的initialMulticaster是一个广播器,初始化EventPublishingRunListener的时候,将之前加载到SpringApplication中的监听器设置到这个广播器里面,以便执行下一步listener.start()方法:

9726385e39ef8126e04ebe9e85ed9e8c.png

每一个监听器都会广播一个事件,广播器负责根据不同的场景广播不同的事件,阅读源码可以发现可以广播如下这些事件:

c6f812026ff25ae642aa6315a484beb8.png

而监听器实现了ApplicationListener接口,初始化EventPublishingRunListener时候,通过广播器把这些监听器添加到ApplicationListener,这样监听器initialMulticaster.multicastEvent就触发了监听器的事件:

f9a9ac026e7be951d748f8f0ae5d6067.png
cd9c099aaf72ab1d1b8c79ed88720b43.png

看见了listener.onApplicationEvent(event);是不是很熟悉?

我们平时实现自己实现一个listener是不是也要实现这个方法?

监听器加载的时候是不是就自动执行这个方法了?

分析到这里是不是就知道了SpringBoot在启动的时候是如何加载监听器并执行这些监听器里面的onApplicationEvent方法了?

我们从META-INF/spring.factories中:

618fc77c7e09f051949fe756d8bdbe37.png

找一个监听了ApplicationEvent事件的监听器LoggingApplicationListener看看:

ec8afaf7f56d49fdc0413288447dd010.png

在这个listener的onApplicationEvent方法设置断点,debug启动时候大家可以发现当执行listeners.starting();这句代码的时候,一旦执行

this.initialMulticaster.multicastEvent

广播器广播事件时候,便立即进入监听器的onApplicationEvent方法中去执行监听器的实现逻辑。

这样通过getRunListeners()方法获取的监听器就通过listeners.starting()方法全部执行完毕了。

但是此处只是执行监听了ApplicationEvent事件的监听器。这些预先执行的监听器其实还是为了下一步创建spring容器做好准备工作。

实际上监听器的执行会伴随着整个SpringBoot的启动过程。根据不同的事件类型来执行不同的监听器,但是流程都是上述分析的流程,都是通过initialMulticaster广播器来广播监听器监听的事件,你一广播,我这个监听器就立即执行,基于事件驱动的思想!

大家在平时写代码的过程中有采用过事件驱动的编程方式吗?

下次为大家继续分析SpringBoot源码的Spring容器准备、启动环节。

欢迎大家关注我,一起学习、分析SpringBoot源码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值