【详细学习SpringBoot核心源码之监听器原理-5(观察者设计模式、初始化并加载监听器核心流程、事件的发布器核心流程、SpringBoot中默认的监听器以及默认的事件类型)】

一.知识回顾

【0.SpringBoot专栏的相关文章都在这里哟,后续更多的文章内容可以点击查看】
【1.SpringBoot初识之Spring注解发展流程以及常用的Spring和SpringBoot注解】
【2.SpringBoot自动装配之SPI机制&SPI案例实操学习&SPI机制核心源码学习】
【3.详细学习SpringBoot自动装配原理分析之核心流程初解析-1】
【4.详细学习SpringBoot自动装配原理之自定义手写Starter案例实操实战-2】
【5.IDEA中集成SpringBoot源码环境详细步骤讲解】
【6.初识SpringBoot核心源码之SpringApplication构造器以及run方法主线流程-3】
【7.详细学习SpringBoot核心源码之SpringApplication构造器&Run方法源码详细流程-4】

二.观察者设计模式

在学习SpringBoot源码的监听器之前,我们必须提前学习一下观察者设计模式,观察者设计模式在我之前写过的设计模式专栏中详细讲解过,大家先去学习一下观察者设计模式,然后我们再来学习一下SpringBoot监听器就会更加明白了。话不多说,上链接。
【Java中23种面试常考的设计模式之观察者模式(Observer)---行为型模式】

下面这几句话很重要:
发布器相当于是观察者设计模式当中的主题,监听器listener相当于是观察者设计模式当中的observer,每一个listener用来监听不同的事件。
发布器中有一个集合专门用来存储所有的listener,发布器发布事件的本质就是遍历属性集合,执行每一个listener中的onApplicationEvent()方法。

三.SpringBoot源码之监听器设计

3.1 初始化并加载监听器

之前的文章我们学习过在SpringApplication的构造方法中会加载所有声明在spring.factories中的监听器。
在这里插入图片描述

SpringApplication中初始化并加载所有监听器的核心逻辑代码

/**
	 * Create a new {@link SpringApplication} instance. The application context will load
	 * beans from the specified primary sources (see {@link SpringApplication class-level}
	 * documentation for details. The instance can be customized before calling
	 * {@link #run(String...)}.
	 * @param resourceLoader the resource loader to use
	 * @param primarySources the primary bean sources
	 * @see #run(Class, String[])
	 * @see #setSources(Set)
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		// 传递的resourceLoader为null
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		// 记录主方法的配置类名称
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		// 记录当前项目的类型
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
		// 加载配置在spring.factories文件中的ApplicationContextInitializer对应的类型并实例化
		// 并将加载的数据存储在了 initializers 成员变量中。
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		// 初始化监听器 并将加载的监听器实例对象存储在了listeners成员变量中
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		// 反推main方法所在的Class对象 并记录在了mainApplicationClass对象中
		this.mainApplicationClass = deduceMainApplicationClass();
	}

setListeners为核心方法
在这里插入图片描述
通过debug我们可以知道加载的监听器就是key为ApplicationListener.class的所有监听器,默认加载的11个监听器
在这里插入图片描述
在这里插入图片描述

3.2 SpringApplication.run()方法中获取所有发布事件的发布器

核心方法getRunListeners
在这里插入图片描述

run方法中获取事件发布器的方法getRunListeners()
在这里插入图片描述

进入getRunListeners方法
在这里插入图片描述

进入getSpringFactoriesInstances方法,并传入SpringApplicationRunListener.class类对象
在这里插入图片描述

spring.factories文件中对应的SpringApplicationRunListener事件发布器

在这里插入图片描述
实例化操作就会执行EventPublishingRunListener.
image.png

回退并进入SpringApplicationRunListeners方法,将从配置文件中加载的集合放入到属性集合当中去。
在这里插入图片描述

接下来就是一个小转折,发布器发布事件,监听器监听到发布的事件并作出相关的逻辑操作

首先我们学习的就是项目启动后,发布器发布事件的主入口方法
在这里插入图片描述

进入starting方法,挨个遍历我们的发布器,并去发布相关的事件

在这里插入图片描述

进入其中的重载构造方法,starting()
在这里插入图片描述

再进入它的实现方法。
在这里插入图片描述

然后再进入multicastEvent方法,传入ApplicationStartingEvent类型的事件

在这里插入图片描述

然后执行重载的方法,监听器的同步和异步调用,我们可以看到具体的触发逻辑

在这里插入图片描述

image.png
继续进入invokeListener方法,查看具体逻辑
在这里插入图片描述

需要继续进入doInvokeListener方法,查看具体逻辑操作。
在这里插入图片描述
学源码必须刨根问题,所以我们需要进入到ApplicationListener接口一探究竟。
在这里插入图片描述

跟到这里,后面的事件发布与监听器的处理逻辑就差不多是一致了。到这儿对应SpringBoot中的监听器这块就分析的差不多了。下篇文章我们将要学习的就是SpringBoot的核心配置文件,SpringBoot的属性文件中的信息什么时候加载的就是在这些内置的监听器中完成的。

四.SpringBoot中默认的监听器以及默认的事件类型

4.1 SpringBoot中默认的监听器

SpringBoot中给我们提供的默认的监听器,这些都定义在spring.factories文件中。

监听器监听事件说明
ClearCachesApplicationListenerContextRefreshedEvent当触发ContextRefreshedEvent事件会清空应用的缓存
ParentContextCloserApplicationListenerParentContextAvailableEvent触发ParentContextAvailableEvent事件会完成父容器关闭的监听器
CloudFoundryVcapEnvironmentPostProcessorApplicationPreparedEvent判断环境中是否存在VCAP_APPLICATION或者VCAP_SERVICES。如果有就添加Cloud Foundry的配置;没有就不执行任何操作。
FileEncodingApplicationListenerApplicationEnvironmentPreparedEvent文件编码的监听器
AnsiOutputApplicationListenerApplicationEnvironmentPreparedEvent根据 spring.output.ansi.enabled参数配置 AnsiOutput
ConfigFileApplicationListenerApplicationEnvironmentPreparedEvent <br>ApplicationPreparedEvent完成相关属性文件的加载,application.properties
application.yml
前面源码内容详细讲解过
DelegatingApplicationListenerApplicationEnvironmentPreparedEvent监听到事件后转发给环境变量 context.listener.classes指定的那些事件监听器
ClasspathLoggingApplicationListenerApplicationEnvironmentPreparedEvent <br>ApplicationFailedEvent一个SmartApplicationListener,对环境就绪事件ApplicationEnvironmentPreparedEvent/应用失败事件ApplicationFailedEvent做出响应,往日志DEBUG级别输出TCCL(thread context class loader)的classpath。
LoggingApplicationListenerApplicationStartingEvent <br>ApplicationEnvironmentPreparedEvent <br>ApplicationPreparedEvent <br>ContextClosedEvent <br>ApplicationFailedEvent配置 LoggingSystem。使用 logging.config环境变量指定的配置或者缺省配置
LiquibaseServiceLocatorApplicationListenerApplicationStartingEvent使用一个可以和Spring Boot可执行jar包配合工作的版本替换liquibase ServiceLocator
BackgroundPreinitializerApplicationStartingEvent <br>ApplicationReadyEvent <br>ApplicationFailedEvent尽早触发一些耗时的初始化任务,使用一个后台线程

4.2 SpringBoot中默认的事件

SpringBoot中的所有的事件都是继承于 ApplicationEvent这个抽象类,在SpringBoot启动的时候会发布如下的相关事件,而这些事件其实都实现了 SpringApplicationContext接口。

事件说明
ApplicationStartingEvent容器启动的事件
ApplicationEnvironmentPreparedEvent应用处理环境变量相关的事件
ApplicationContextInitializedEvent容器初始化的事件
ApplicationPreparedEvent应用准备的事件
ApplicationFailedEvent应用启动出错的事件
ApplicationStartedEvent应用Started状态事件
ApplicationReadyEvent应用准备就绪的事件

这些事件都是属于SpringBoot启动过程中涉及到的相关的事件

好了,本篇文章【详细学习SpringBoot核心源码之监听器原理-5(观察者设计模式、初始化并加载监听器核心流程、事件的发布器核心流程、SpringBoot中默认的监听器以及默认的事件类型)】到学习到这里,下篇文章我们将先来学习一下自定义监听器的实现过程,然后再来学习配置文件的核心流程。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

硕风和炜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值