当前位置: 首页 > news >正文

SpringBoot源码阅读(4)——事件

从监听器到事件

SpringApplication运行中触发事件,多播器发送事件到监听器,监听器处理事件。
SpingApplication中事件都是经过SpringApplicationRunListeners类传送到各个监听器。
以starting事件为例

void starting(ConfigurableBootstrapContext bootstrapContext, Class<?> mainApplicationClass) {doWithListeners("spring.boot.application.starting", (listener) -> listener.starting(bootstrapContext),(step) -> {if (mainApplicationClass != null) {step.tag("mainApplicationClass", mainApplicationClass.getName());}});
}
private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction,Consumer<StartupStep> stepAction) {StartupStep step = this.applicationStartup.start(stepName);this.listeners.forEach(listenerAction);if (stepAction != null) {stepAction.accept(step);}step.end();
}

这里的this.listeners是一个SpringApplicationRunListener的集合,而SpringApplicationRunListener的实现类配置中只有一个EventPublishingRunListener
starting事件执行的是EventPublishingRunListenerstarting方法

public void starting(ConfigurableBootstrapContext bootstrapContext) {this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(bootstrapContext, this.application, this.args));
}

这里就找到了第一个事件ApplicationStartingEvent
接着往下执行

public void multicastEvent(ApplicationEvent event) {multicastEvent(event, resolveDefaultEventType(event));
}@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));Executor executor = getTaskExecutor();for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {if (executor != null) {executor.execute(() -> invokeListener(listener, event));}else {invokeListener(listener, event);}}
}

ResolvableType类这里略过,里面涉及的内容较多,在这里的具体作用是从类的注解、泛型、继承结构、代理上获取原始的目标对象。
这里要注意的方法getApplicationListeners,根据事件类型获取监听器,然后执行。
查找的过程比较长,这里列举一些比较重要的方法
AbstractApplicationEventMulticastergetApplicationListenersretrieveApplicationListenerssupportsEvent
supportsEvent方法中有具体的判断逻辑

protected boolean supportsEvent(ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
}

根据监听器的类型调用监听器类的支持事件类型supportsEventType和支持事件源类型supportsSourceType两个方法,来判断是否传播到该监听器。
ApplicationListener监听器有多个实现。

  • ClearCachesApplicationListener
  • ParentContextCloserApplicationListener
  • FileEncodingApplicationListener
  • AnsiOutputApplicationListener
  • DelegatingApplicationListener
  • LoggingApplicationListener
  • EnvironmentPostProcessorApplicationListener
  • BackgroundPreinitializer

ClearCachesApplicationListener

结构:
implements ApplicationListener<ContextRefreshedEvent>
支持的事件类型:

  • ContextRefreshedEvent
  • ApplicationContextEvent
  • ApplicationEvent

支持的事件源:
无限制

ParentContextCloserApplicationListener

结构:
implements ApplicationListener<ParentContextAvailableEvent>, ApplicationContextAware, Ordered
支持的事件类型

  • ParentContextAvailableEvent
  • ApplicationEvent

支持的事件源:
无限制

FileEncodingApplicationListener

结构:
implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered
支持的事件类型:

  • ApplicationEnvironmentPreparedEvent
  • SpringApplicationEvent
  • ApplicationEvent

支持的事件源:
无限制

AnsiOutputApplicationListener

结构:
implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered
支持的事件类型:

  • ApplicationEnvironmentPreparedEvent
  • SpringApplicationEvent
  • ApplicationEvent

支持的事件源:
无限制

DelegatingApplicationListener

结构:
implements ApplicationListener<ApplicationEvent>, Ordered
支持的事件类型:

  • ApplicationEvent

支持的事件源:
无限制

LoggingApplicationListener

结构:
implements GenericApplicationListener
支持的事件类型:

  • ApplicationStartingEvent
  • ApplicationEnvironmentPreparedEvent
  • ApplicationPreparedEvent
  • ContextClosedEvent
  • ApplicationFailedEvent

支持的事件源:

  • SpringApplication
  • ApplicationContext

EnvironmentPostProcessorApplicationListener

结构:
implements SmartApplicationListener, Ordered
支持的事件类型:

  • ApplicationEnvironmentPreparedEvent
  • ApplicationPreparedEvent
  • ApplicationFailedEvent

支持的事件源:

  • SpringApplication
  • ApplicationContext

BackgroundPreinitializer

结构:
implements ApplicationListener<SpringApplicationEvent>
支持的事件类型:

  • SpringApplicationEvent
  • ApplicationEvent

支持的事件源:
无限制

事件

EventPublishingRunListener的方法还有上面的事件类型,SpringBoot中的事件类型有:

  • ApplicationStartingEvent
  • ApplicationEnvironmentPreparedEvent
  • ApplicationContextInitializedEvent
  • ApplicationPreparedEvent
  • ApplicationStartedEvent
  • ApplicationReadyEvent

除了multicastEvent多播事件,还有下面两个方法发布事件。

@Override
public void started(ConfigurableApplicationContext context, Duration timeTaken) {context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context, timeTaken));AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
}@Override
public void ready(ConfigurableApplicationContext context, Duration timeTaken) {context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context, timeTaken));AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
}

事实上,这些事件都在一个包路径下。
在这里插入图片描述

ApplicationStartingEvent

注释:

事件在启动SpringApplication后尽早发布——在Environment或ApplicationContext可用之前,但在ApplicationListeners注册之后。事件的来源是SpringApplication本身,但要注意在早期阶段不要过多地使用其内部状态,因为它可能会在生命周期的后期被修改。

使用的翻译,不甚明了,得看看怎么这个事件触发后,监听器做了什么。

ApplicationEnvironmentPreparedEvent

注释:

当SpringApplication启动并且环境首次可用于检查和修改时发布的事件

ApplicationContextInitializedEvent

注释:

在启动SpringApplication、准备ApplicationContext和调用ApplicationContextInitializer时发布的事件,但在加载任何bean定义之前。

ApplicationPreparedEvent

注释:

当SpringApplication正在启动并且ApplicationContext已完全准备好但未刷新时发布的事件。将加载bean定义,并且环境已准备好在此阶段使用

ApplicationStartedEvent

注释:

刷新应用程序上下文后,但在调用任何应用程序和命令行运行程序之前发布的事件

ApplicationReadyEvent

注释:

事件尽可能晚地发布,以指示应用程序已准备好为请求提供服务。事件的来源是SpringApplication本身,但要注意修改其内部状态,因为届时所有初始化步骤都已完成

ApplicationFailedEvent

注释:

SpringApplication在启动失败时发布的事件

相关文章:

SpringBoot源码阅读(4)——事件

从监听器到事件 SpringApplication运行中触发事件&#xff0c;多播器发送事件到监听器&#xff0c;监听器处理事件。 SpingApplication中事件都是经过SpringApplicationRunListeners类传送到各个监听器。 以starting事件为例 void starting(ConfigurableBootstrapContext boo…...

EDI安全:如何在2024年保护您的数据免受安全和隐私威胁

电子数据交换&#xff08;EDI&#xff09;支持使用标准化格式在组织之间自动交换业务文档。这种数字化转型彻底改变了业务通信&#xff0c;消除了对纸质交易的需求并加速了交易。然而&#xff0c;随着越来越依赖 EDI 来传输发票、采购订单和发货通知等敏感数据&#xff0c;EDI …...

RabbitMQ快速入门 - 图像化界面的简单操作

目录 1、RabbitMQ的安装 2、RabbitMQ基本介绍 3、简单案例 4、数据隔离 1、RabbitMQ的安装 官网链接&#xff1a;rabbitmq官网 &#xff08;官网很详细&#xff0c;也可以在官网学习啦~&#xff09; 基础入门&#xff1a;自主学习&#xff1a;最新版本&#xff1a;安装我…...

新版亚组交互效应函数(P for interaction)newscitb5 1.3版本发布--用于一键生成交互效应表

在SCI文章中&#xff0c;交互效应表格&#xff08;通常是表五&#xff09;能为文章锦上添花&#xff0c;增加文章的信服力&#xff0c;增加结果的可信程度&#xff0c;还能进行数据挖掘。什么是亚组&#xff0c;通常就是特殊类型人群&#xff0c;比如男女&#xff0c;种族等&am…...

gpt讲 Observable 对象

什么是 Observable&#xff1f; Observable 是一种用于处理异步数据流的数据类型。它可以发出多个值&#xff0c;这些值可以是同步或者异步产生的&#xff0c;并且可以在时间上发生变化。在 Angular 中&#xff0c;HttpClient 返回的响应对象、事件流以及许多其他异步任务都可…...

STM32的SPI接口详解

目录 1.SPI简介 2.SPI工作原理 3.SPI时序 3.1 CPOL&#xff08;Clock Polarity&#xff0c;时钟极性&#xff09;&#xff1a; 3.2 CPHA&#xff08;Clock Phase&#xff0c;时钟相位&#xff09;&#xff1a; 3.3 四种工作模式 4.相关代码 4.1使能片选信号 4.2使能通…...

谷歌+火狐浏览器——实现生成二维码并实现拖动——js技能提升

最新遇到的问题&#xff1a;前两个二维码拖动不了&#xff0c;只有第三个一维码生成后&#xff0c;才可以拖拽 【问题】&#xff1a;出现在都是绝对定位&#xff0c;但是没有指定z-index导致的。 解决办法&#xff1a;在方法中添加一个变量 renderDrag(id) {var isDragging f…...

128陷阱详解(从源码分析)

1、128陷阱描述 Integer 整型 -128~127 超过这个范围&#xff0c;比较会不准确 例子 public static void main(String[] args) {Integer a128;Integer b128;Integer e127;Integer f127;System.out.println(ab); //输出falseSystem.out.println(a.equals(b)); //输出trueS…...

点云处理实操 基于多项式重构的平滑和法线估计

目录 基于多项式重构的平滑和法线估计 一、什么是移动最小二乘法(Moving Least Squares, MLS) 二、算法原理 三、算法应用 四、PCL代码实践 基于多项式重构的平滑和法线估计 原文地址:Smoothing and normal estimation based on polynomial reconstruction — Point Cl…...

MongoDB在Linux下的安装与基本操作指南

MongoDB是一款高性能、开源的NoSQL数据库系统&#xff0c;特别适合处理大规模数据存储应用。本文将详细介绍MongoDB在Linux系统&#xff08;以Ubuntu为例&#xff09;上的安装步骤&#xff0c;以及如何进行基本的数据库操作&#xff0c;帮助你快速上手MongoDB。 一、在Linux上…...

端口占用快速解决

netstat -aon|findsstr 8989 taskkill /pid 13221 -t -f 命令解释 1.检查网络连接状态 2.终止特定进程 netstat -aon | findstr 8989 netstat: 这是一个网络状态统计工具&#xff0c;可以显示活动的网络连接、路由表、接口表、多播成员信息等。-a: 显示所有连接和监听端口。通…...

普中51单片机:矩阵按键扫描与应用详解(五)

文章目录 引言电路图开发板IO连接矩阵键盘的工作原理行列扫描逐行/逐列扫描 LCD1602代码库代码演示——暴力扫描代码演示——数码管(行列式)代码演示——线翻转法代码演示——LCD1602密码锁 引言 矩阵按键是一种通过行列交叉连接的按键阵列&#xff0c;可以有效地减少单片机I/…...

SQLite Glob 子句

SQLite Glob 子句 SQLite 的 GLOB 子句是一种强大的搜索工具&#xff0c;用于在数据库中执行模式匹配操作。它类似于 SQL 中的 LIKE 子句&#xff0c;但 GLOB 使用的是基于文件系统的通配符&#xff0c;而不是 SQL 的百分比 (%) 和下划线 (_) 通配符。在本文中&#xff0c;我们…...

Redis基础教程(十七):Redis数据备份与恢复

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…...

基于FPGA的千兆以太网设计(1)----大白话解释什么是以太网

1、什么是以太网? 还记得初学以太网的时候,我就被一大堆专业名词给整懵了:什么以太网,互联网,MAC,IP,局域网,万维网,网络分层模型等等等等。慢着!我学的不是以太网吗?怎么出来这么一大堆东西? 啊!以太网究竟是什么?别急,我接下来就尽量用通俗的大白话来给你解释…...

wordpress的restfull API使用教程,之如何用postman调试API,以便能使用vue等前端框架开发主题

文章目录 API开发手册在postman中调试这里以 post 一篇文章为例&#xff0c;讲解如何调试&#xff1a; 步骤 1&#xff1a;生成应用密码步骤 2&#xff1a;配置Postman步骤 3&#xff1a;创建文章 参考链接 API开发手册 官方API手册&#xff1a;https://developer.wordpress.o…...

刷题刷题刷题

P1123 取数游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 思路&#xff1a; 从1,1开始dfs&#xff0c;若行数x>n则立马刷新最大值退出搜索&#xff0c;若y>m则进入下一行从第一列开始搜索即x1,y1&#xff0c;对当前的搜索点x,y的八个方向进行1,因为不能相邻 AC:…...

【Spring Boot】统一异常处理

目录 统一异常处理一. 概念二. 全局异常处理三. 处理特定异常 统一异常处理 一. 概念 其实统一异常是运用了AOP&#xff08;对某一类事情的集中处理&#xff09;的思维&#xff0c;简单概括就是在我们进行前后端数据交互的时候&#xff0c;抛出的任何的异常都能够自动捕获然后…...

java —— tomcat 部署项目

一、通过 war 包部署 1、将项目导出为 war 包&#xff1b; 2、将 war 包放置在 tomcat 目录下的 webapps 文件夹下&#xff0c;该 war 包稍时便自动解析为项目文件夹&#xff1b; 3、启动 tomcat 的 /bin 目录下的 startup.bat 文件&#xff0c;此时即可从浏览器访问项目首页…...

数据库的优点和缺点分别是什么

数据库作为数据存储和管理的核心组件&#xff0c;具有一系列显著的优点&#xff0c;同时也存在一些潜在的缺点。以下是对数据库优点和缺点的详细分析&#xff1a; 数据库的优点 数据一致性&#xff1a;数据库通过事务管理、锁机制、并发控制等技术手段&#xff0c;确保多个用户…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...