SpringBoot启动源码探究---listeners.starting()
1.首先调用starting()方法,其内部是一个对所有listener的starting()调用的for循环,然后每个listener调用另一个starting方法,其内部调用multicastEvent方法,其又调用其他multicastEvent方法,其又继续调用其他的multicastEvent方法,然后在里面进行了这样的逻辑:先根据事件类型获取到合适的监听器,然后对这些合适的监听器遍历,每一个监听器都开启一个独立的线程去执行监听(具体放在下一节)

2.其中获取到合适的监听器很重要,如何匹配?
下述方法表示先从缓存中获取,如果没有再老老实实地检索合适的监听器,然后再将检索到的监听器放进缓存,最后返回监听器,这样做的好处是下次再用到相同的监听器,可以走捷径,很快.其中有一个核心方法:检索监听器

3.如何检索监听器?retrieveApplicationListener方法
该方法表示从两条途径检索合适的监听器:一条是从现有的监听器列表中检索,一条是从现有的监听器实例列表中检索.
但不管从哪里检索,它们的核心检索方法都是一样的--->判断是否支持该事件类型的supportsEvent()方法

4.supportsEvent()方法如何运作?
该方法表示当前遍历到的监听器必须同时支持事件类型和事件源类型,才能成为合适的监听器.核心方法是supportsEventType()和supportsSourceType().

5.supportsEventType()和supportsSourceType()两个方法看上去长的差不多,没错!它们的原理也差不多,都是两个字:"比较"看是否支持.所以我们只需要看supportsEventType就明白如何运作.
该方法有个if-else判断,两个分支的核心方法名字看上去还不一样,其实if中的supportsEventType()方法本质和else中的isAssignable()目的都一样,也就是名称不一样而已,核心还是两个字:"比较"

6.说了两次"比较"了,那什么是比较呢?
就是将方法指定的事件类型与传入的事件类型比较,如果前者是后者的超类,则合适,否则不合适,如下:一个例子

补充:此处的isAssignableFrom()方法已经到底了,是native方法,作用就是比较前者是否是后者的爹.
7.上面只是ConfigFileApplicationListener监听器中supportsEventType方法的实现,其实很多监听器都有自己的实现,每种监听器都在自己的实现中规定了自己感兴趣的事件类型和事件源类型,正因此,才能与传入的事件类型做比较,从而判断自己应不应该监听它.如下面这个监听器,其感兴趣的类型与上面不同:

8.说完了如何比较事件类型,也就说完了如何比较事件源类型,因为他们的原理完全一样,都是通过判断传入的类型是不是自己内定类型的子类/实现类,从而确定要不要监听它.
但是,不同的监听器都是调用同一个方法去比较的,如何做到的?这就是本源码分析中一个比较有意思的问题,答案是这里使用了面向接口编程
所有的监听器都实现了GnericApplicationListener,当真正的实例调用supportsEventType()方法时,它们只会调用到自己所在的实现类的方法,从而达到"和而不同".
9.以上浅见,感谢指正!
SpringBoot启动源码探究---listeners.starting()的更多相关文章
- SpringBoot启动源码探究----configureHeadlessProperty()方法
该方法只做了一件事:设置了一个名为java.awt.headless的系统属性,源码如下: private void configureHeadlessProperty() { System.setP ...
- SpringBoot启动源码探究---getRunListener()
该方法目的是获取SpringApplicationRunListener getRunListener()-----调用----> getSpringFactoriesInstances()-- ...
- SpringBoot启动源码及自定义starter
为什么springboot工程能够在mian方法中完成启动呢?需要大家掌握的有几个点:1.SPISPI在springboot中是去读取META-INF/spring.factories目录的配置文件内 ...
- Springboot启动源码详解
我们开发任何一个Spring Boot项目,都会用到如下的启动类 @SpringBootApplication public class Application { public static voi ...
- spring-boot-2.0.3启动源码篇二 - run方法(一)之SpringApplicationRunListener
前言 Springboot启动源码系列还只写了一篇,已经过去一周,又到了每周一更的时间了(是不是很熟悉?),大家有没有很期待了?我会尽量保证启动源码系列每周一更,争取不让大家每周的期望落空.一周之中可 ...
- spring-boot-2.0.3启动源码篇一 - SpringApplication构造方法
前言 spring-boot-2.0.3应用篇 - shiro集成,实现了spring-boot与shiro的整合,效果大家也看到了,工程确实集成了shiro的认证与授权功能.如果大家能正确搭建起来, ...
- spring-boot-2.0.3之quartz集成,数据源问题,源码探究
前言 开心一刻 着火了,他报警说:119吗,我家发生火灾了. 119问:在哪里? 他说:在我家. 119问:具体点. 他说:在我家的厨房里. 119问:我说你现在的位置. 他说:我趴在桌子底下. 11 ...
- SpringBoot读取配置文件源码探究
1. SpringBoot读取配置文件源码探究 1.1. 概览 springboot的源码是再原来的Spring源码上又包了一层,看过spring源码都知道,当我们从入口debug进去的时候,原来的S ...
- spring-boot-2.0.3启动源码篇四 - run方法(三)之createApplicationContext
前言 此系列是针对springboot的启动,旨在于和大家一起来看看springboot启动的过程中到底做了一些什么事.如果大家对springboot的源码有所研究,可以挑些自己感兴趣或者对自己有帮助 ...
随机推荐
- [python3.6+opencv] 02 imwrite-打开图像后保存退出还是不保存退出的问题
加载一个灰度图,显示图片,按下’s’键保存后退出, 或者按下 ESC 键退出不保存 # -*- coding: utf-8 -*- import numpy as np import cv2 as c ...
- Sonar Java 规则插件开发 (基于阿里开发手册)
引言 最近在做Sonar静态代码扫描管理,以此顺手接了Sonar的插件开发,基于阿里开发手册进行开发,在整体开发过程中,其中还是遇到不少坑位,也以此给大家做相应借鉴官网Demo演示插件开发地址:htt ...
- echarts 自定义主题
https://blog.csdn.net/flitrue/article/details/52841338 import $echarts from 'echarts' import 'echar ...
- vue 线上不支持put方法
在app.js中加上 // Vue.http.options.emulateHTTP = true Vue.http.options.timeout = 15000
- 【oracle入门】SQL的命令动词
SQL的功能 命令动词 数据定义 CREATE,DROP,ALTER 数据操纵 SELECT,INSERT,UPDATE,DELETE 数据控制 CRANT,REVOKE
- 如何删除新添加的项目Module
今天 new 了一个Module ,使用的是library,发现不是我想要的,于是果断删除它 但是如何删除呢,却一直找不到这个删除的delete 后来发现在这里可以删除 打开 file -> ...
- 项目里如何访问AppDelegate
项目里面访问AppDelegate做全局变量用有好几种方式 最原始就是 AppDelegate *appDelegate = (AppDelegate *)[[UIApplication shared ...
- webshell导致项目崩溃
mysql挂死,无法启动,解决mysql无法启动: /etc/my.cnf配置文件中innodb_force_recovery=1然后service mysqld start/etc/my.cnf配置 ...
- Oracle SQL Developer 连接数据库问题总结
一.使用scott用户登录的问题 说明:Oracle如果是初次使用用户,scott用户是没有解锁的.所以要先解锁.注:scott是个测试用户. 具体步骤: 1.在Dos命令下输入 sqlplus 可以 ...
- 我的代码-unsupervised learning
# coding: utf-8 # In[1]: import pandas as pdimport numpy as npfrom sklearn import treefrom sklearn.s ...