Spring Boot中的各种事件

spring boot 各种事件贯穿整个启动的生命周期,读懂了这些事件也差不多理解了springboot的启动流程。

SpringApplicationRunListener中的事件

接口org.springframework.boot.SpringApplicationRunListener定义了spring启动过程中各个事件被触发的顶层方法

public interface SpringApplicationRunListener {
        
        default void starting() {
        }

        default void environmentPrepared(ConfigurableEnvironment environment) {
        }
        
        default void contextPrepared(ConfigurableApplicationContext context) {
        }
        
        default void contextLoaded(ConfigurableApplicationContext context) {
        }
        
        default void started(ConfigurableApplicationContext context) {
        }
        
        default void running(ConfigurableApplicationContext context) {
        }
        
        default void failed(ConfigurableApplicationContext context, Throwable exception) {
        }

    }

SpringApplicationRunListener的方法定义很讲究,方法从上到下的顺序也正好是各事件触发的顺序。SpringApplicationRunListener接口的唯一具体实现类是org.springframework.boot.context.event.EventPublishingRunListener

  1. starting接口表示springboot程序准备开始启动,这是最早的事件触发方法,它将触发ApplicationStartingEvent事件。这个事件一般没人关心,目前spring中没有任何逻辑实现依赖于这个事件。
	//EventPublishingRunListener
	@Override
	public void starting() {
		this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
	}
  1. environmentPrepared接口方法表示Environment对象准备好了,它将触发ApplicationEnvironmentPreparedEvent事件.
	//EventPublishingRunListener
	@Override
	public void environmentPrepared(ConfigurableEnvironment environment) {
		this.initialMulticaster
				.multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
	}

不论是本地配置文件还是云端配置中心,它们的配置内容读取都依赖于此事件。

ConfigFileApplicationListener本地配置文件监听器

public class ConfigFileApplicationListener implements EnvironmentPostProcessor, SmartApplicationListener, Ordered{
@Override
	public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
		return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType)
				|| ApplicationPreparedEvent.class.isAssignableFrom(eventType);
	}

	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		if (event instanceof ApplicationEnvironmentPreparedEvent) {
			onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
		}
		if (event instanceof ApplicationPreparedEvent) {
			onApplicationPreparedEvent(event);
		}
	}
}

BootstrapApplicationListener云端配置中心监听器

public class BootstrapApplicationListener
		implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
		
}
  1. contextPrepared表示ApplicationContext实例化后,所有的ApplicationContextInitializer实例的initialize已经被依次调用执行完毕。
    这个方法将触发ApplicationContextInitializedEvent事件
    在这里插入图片描述
	//EventPublishingRunListener
	@Override
	public void contextPrepared(ConfigurableApplicationContext context) {
		this.initialMulticaster
				.multicastEvent(new ApplicationContextInitializedEvent(this.application, this.args, context));
	}
  1. contextLoaded 方法表示ApplicationContext的各种资源已经被读取加载完毕(主要是各种BeanDefination的读取),但还没有进行上下文刷新。此方法将触发ApplicationPreparedEvent事件
	//EventPublishingRunListener
	@Override
	public void contextLoaded(ConfigurableApplicationContext context) {
		for (ApplicationListener<?> listener : this.application.getListeners()) {
			if (listener instanceof ApplicationContextAware) {
				((ApplicationContextAware) listener).setApplicationContext(context);
			}
			context.addApplicationListener(listener);
		}
		this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
	}
  1. started表示ApplicationContext的refresh刷新完成,但CommandLineRunnersApplicationRunner 这些函数接口还未执行。
	//EventPublishingRunListener
	@Override
	public void started(ConfigurableApplicationContext context) {
		context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));
		AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
	}
  1. running方法表示CommandLineRunnersApplicationRunner函数接口也都被调用执行完毕,它是springboot正常启动过程中的最后一个事件,它标志着项目已完全启动,它将触发ApplicationReadyEvent事件。
	//EventPublishingRunListener
	@Override
	public void running(ConfigurableApplicationContext context) {
		context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context));
		AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
	}
  1. failed表示项目启动过程中出现异常,启动过程中的任意一阶段都可能出错。
	//EventPublishingRunListener
	@Override
	public void failed(ConfigurableApplicationContext context, Throwable exception) {
		ApplicationFailedEvent event = new ApplicationFailedEvent(this.application, this.args, context, exception);
		if (context != null && context.isActive()) {
			// Listeners have been registered to the application context so we should
			// use it at this point if we can
			context.publishEvent(event);
		}
		else {
			// An inactive context may not have a multicaster so we use our multicaster to
			// call all of the context's listeners instead
			if (context instanceof AbstractApplicationContext) {
				for (ApplicationListener<?> listener : ((AbstractApplicationContext) context)
						.getApplicationListeners()) {
					this.initialMulticaster.addApplicationListener(listener);
				}
			}
			this.initialMulticaster.setErrorHandler(new LoggingErrorHandler());
			this.initialMulticaster.multicastEvent(event);
		}
	}

其他事件

ApplicationContext在刷新完成后,生命周期处理器的默认实现类DefaultLifecycleProcessor的onRefresh方法会被调用,并发布ContextRefreshedEvent事件。
在这里插入图片描述DefaultLifecycleProcessor.onRefresh会调用所有实现SmartLifecycle接口的Spring Bean对象的start方法。

//DefaultLifecycleProcessor

	@Override
	public void onRefresh() {
		startBeans(true);
		this.running = true;
	}
	private void startBeans(boolean autoStartupOnly) {
		Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
		Map<Integer, LifecycleGroup> phases = new HashMap<>();
		lifecycleBeans.forEach((beanName, bean) -> {
			if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
				int phase = getPhase(bean);
				LifecycleGroup group = phases.get(phase);
				if (group == null) {
					group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
					phases.put(phase, group);
				}
				group.add(beanName, bean);
			}
		});
		if (!phases.isEmpty()) {
			List<Integer> keys = new ArrayList<>(phases.keySet());
			Collections.sort(keys);
			for (Integer key : keys) {
				phases.get(key).start();
			}
		}
	}

WebServerStartStopLifecycle也实现了SmartLifecycle接口,此start方法将启动Tomcat容器,并发布ServletWebServerInitializedEvent事件。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/730360.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript的学习之强制类型转换

目录 一、什么是强制类型转换 二、其他类型转化为String类型 方式一&#xff1a;调用被转化数据类型的toString()方法 方式二&#xff1a;调用String函数&#xff0c;并将我们要转换的数据添加进去为参数 三、其他类型转化为Number类型 方式一&#xff1a;使用Number()函数…

Python有哪些就业方向?就业市场广阔!

Python是一种跨平台的计算机程序设计语言&#xff0c;是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。Python语言在人工智能的发展下&#xff0c;越来越多计算机企业开始广泛使用&#xff0c;同时Python的就业方向也逐渐广阔。 YesPMP为学习Python的技术人员…

【环境变量问题:计算机删除环境变量的恢复方法;此环境变量太大。此对话框允许将值设置为最长2047个字符】

不小心误删了win10系统环境变量可以试试下文方法恢复。 本方法针对修改环境变量未重启的用户可以使用&#xff0c;如果修改环境变量&#xff0c;然后还重启了&#xff0c;只能说重新来。 方法一&#xff1a;使用命令提示符恢复 被修改的系统Path只是同步到了注册表中&#x…

QListWidget、QMenu、Action、customContextMenuRequested

QListWidget的初始化、清空、Append添加、Insert添加、删除item QListWidget的事件的使用 QToolBox的使用&#xff0c;每个Page可以添加其他控件 QToolBar使用代码添加QMenu,QMenu添加3个Action QToolButton绑定Action 布局 其中 QSplitter比较特殊&#xff0c; 允许在水平或垂…

策略模式:applicationContext.getBeansOfType()方法

applicationContext.getBeansOfType() 一般用来获取某个接口的所有实例Bean 方法定义如下&#xff1a; 入参一般是接口&#xff0c;即interface。响应是个Map结构&#xff0c;key bean在容器中的名称&#xff0c;value bean实列 开发步骤&#xff1a; 1.定义接口 2.定义…

NGINX_十八 nginx 访问控制

十八 nginx 访问控制 1 nginx 访问控制模块 &#xff08;1&#xff09;基于IP的访问控制&#xff1a;http_access_module &#xff08;2&#xff09;基于用户的信任登录&#xff1a;http_auth_basic_module 2 基于IP的访问控制 2.1 配置语法 Syntax&#xff1a;allow addr…

kettle从入门到精通 第七十二课 ETL之kettle 三谈http post(含文件上传),彻底掌握参数传递

场景&#xff1a;群里有个小伙伴在使用http post步骤调用接口时遇到问题&#xff0c;postman调用正常&#xff0c;但是kettle中调用异常。 解决方案&#xff1a;既然postman调用接口正常&#xff0c;肯定是http post步骤中某些参数设置的不正确导致的。那就把常用的方式都梳理下…

C++11 右值引用和移动语义

目录 1.左值引用和右值引用 2.右值引用使用场景&#xff08;移动语义&#xff09;和意义 3.右值引用引用左值及其一些更深入的使用场景分析 4.完美转发 1.左值引用和右值引用 传统的C语法中就有引用的语法&#xff0c;而C11中新增了的右值引用语法特性&#xff0c;所以从现…

云计算考试题

Cloud ❀ 云计算-虚拟化常见的两种架构_裸金属架构和宿主型架构的区别-CSDN博客 为啥要成2 11 bcd 16 acd abcd BCD NAS为啥支持文件存储的协议 选BCD 什么是网络文件系统 选bcd 错题 选abc 选bcd 选 abd

【ARMv8/v9 GIC 系列 4.2 -- GIC CPU Interface 详细介绍】

文章目录 GIC CPU Interface 介绍CPU Interface 主要寄存器 GIC CPU Interface 介绍 A 系列处理器提供 5个管脚来实现中断&#xff0c;分别是&#xff1a; nIRQ&#xff1a;物理普通中断nFIQ&#xff1a;物理快速中断nVIRQ&#xff1a;虚拟普通中断nVFIQ&#xff1a;虚拟快速…

运算放大器(运放)积分器电路

积分器电路 运算放大器(运放)积分器电路是在图2运放反相放大器的电路上增加一个积分电容构成&#xff0c;该积分电容并联在运算放大器的反馈电阻上&#xff0c;见图1。 运算放大器(运放)反相放大器电路 设计目标 输入fMin输入f0dB输入fMax输出VoMin输出VoMax电源Vcc电源Vee1…

【JS重点19】this指向问题总结

目录 一&#xff1a;普通函数this指向 普通函数在严格模式下&#xff1a; 二&#xff1a;箭头函数this指向 this指向说明 不适用this情况 三&#xff1a;改变this指向 1 call() 语法格式&#xff1a; 作用&#xff1a; 2 apply() 语法格式&#xff1a; 作用&#x…

C#.net6.0语言+B/S架构+前后端分离 手术麻醉信息管理系统源码

C#.net6.0语言&#xff0b;B/S架构前后端分离 手术麻醉信息管理系统源码 什么是手术麻醉信息管理系统 满足医院等级评级需求 满足电子病历评级需求 满足科室需求 术前 1、患者术前评估/诊断 2、术前讨论制定手术方案 3、手术准备 4、术前准备 术中 1、送手术室 2、麻…

oracle12c到19c adg搭建(五)dg搭建后进行切换19c进行数据字典升级

一、备库切主库升级 12c切换为19c主库的时候是由低版本到高版本所以cdb和pdb的数据字典需要进行升级才可以让数据与软件版本兼容。 1.1切换 SQL> alter database recover managed standby database finish; Database altered. SQL> alter database commit to switcho…

基于 NXP LS1046 +FPGA系列 CPCI 架构轨道交通专用板卡

基于 NXP LS1046 系列 CPCI 架构轨道板卡 该产品是一款 CPCI 无风扇架构的高可靠性板卡&#xff0c;CPU 选用 NXP LS1046A 系统平台&#xff0c;支持嵌入式 Linux 或者标准 Ubuntu Linux 、凝思等操作系统&#xff0c;轨道交通 EMC 及宽温级别设计&#xff0c;板载多路 M12 高速…

SQLite扩展插件终极集合

作为一个嵌入式数据库引擎&#xff0c;SQLite 与其他数据库管理系统相比&#xff0c;缺少了一些功能。不过 SQLite 提供了一个扩展机制&#xff0c;因此我们可以在网络上找到大量的 SQLite 插件。 今天我们介绍的这个插件叫做 sqlean&#xff0c;它打包了许多流行的 SQLite 扩…

【windows】字体安装手册

windows字体安装手册 1 下载字体文件 百度搜索XXX字体ttf文件进行下载 附&#xff1a;宋体gb2312下载地址&#xff1a; https://www.downza.cn/soft/7780.html 2 字体安装 1.搜索字体 2.将下载的ttf文件拖拽添加 3.关闭办公软件重新打开后&#xff0c;outlook、word、…

装备制造业CRM解决方案

01、数字化转型驱动企业&#xff0c;向“以客户需求驱动创新生产”的智能制造业转变 我国装备制造业经过多年的发展&#xff0c;取得了令人瞩目的成就&#xff0c;形成了门类齐全、具有相当规模和一定水平的产业体系&#xff1b;主要包含通用设备、专用设备、电气机械、交通运…

GPT 模型简史:从 GPT-1 到 GPT-4

文章目录 GPT-1GPT-2GPT-3从 GPT-3 到 InstructGPTGPT-3.5、Codex 和 ChatGPTGPT-4 GPT-1 2018 年年中&#xff0c;就在 Transformer 架构诞生⼀年后&#xff0c;OpenAI 发表了⼀篇题 为“Improving Language Understanding by Generative Pre-Training”的论文&#xff0c;作者…

DS知识点总结--线性表定义及顺序表示

数据结构知识点汇总(考研C版) 文章目录 数据结构知识点汇总(考研C版)二、线性表2.1 线性表的定义和操作2.1.1 线性表的定义2.1.2 线性表的基本操作 2.2 线性表的顺序表示2.2.1 顺序表的定义2.2.2 顺序表上的基本操作的实现 二、线性表 2.1 线性表的定义和操作 2.1.1 线性表的…