SpringBoot3 事件和监听器

news2024/11/23 12:17:44

1. 生命周期监听

场景:监听应用生命周期

1. 监听器-SpringApplicationRunListener

  1. 自定义SpringApplicationRunListener来监听事件;
    1. 编写SpringApplicationRunListener 实现类
    2. META-INF/spring.factories 中配置 org.springframework.boot.SpringApplicationRunListener=自己的Listener,还可以指定一个有参构造器,接受两个参数(SpringApplication application, String[] args)
    3. springboot 在spring-boot.jar中配置了默认的 Listener,如下

在这里插入图片描述

/**
 * Listener先要从 META-INF/spring.factories 读到
 *
 * 1、引导: 利用 BootstrapContext 引导整个项目启动
 *      starting:              应用开始,SpringApplication的run方法一调用,只要有了 BootstrapContext 就执行
 *      environmentPrepared:   环境准备好(把启动参数等绑定到环境变量中),但是ioc还没有创建;【调一次】
 * 2、启动:
 *      contextPrepared:       ioc容器创建并准备好,但是sources(主配置类)没加载。并关闭引导上下文;组件都没创建  【调一次】
 *      contextLoaded:         ioc容器加载。主配置类加载进去了。但是ioc容器还没刷新(我们的bean没创建)。
 *      =======截止以前,ioc容器里面还没造bean呢=======
 *      started:               ioc容器刷新了(所有bean造好了),但是 runner 没调用。
 *      ready:                  ioc容器刷新了(所有bean造好了),所有 runner 调用完了。
 * 3、运行
 *     以前步骤都正确执行,代表容器running。
 */

2. 生命周期全流程

在这里插入图片描述

2. 事件触发时机

1. 各种回调监听器

  • BootstrapRegistryInitializer感知特定阶段:感知引导初始化
    • META-INF/spring.factories
    • 创建引导上下文bootstrapContext的时候触发。
    • application.addBootstrapRegistryInitializer();
    • 场景:进行密钥校对授权。
  • ApplicationContextInitializer感知特定阶段: 感知ioc容器初始化
    • META-INF/spring.factories
    • application.addInitializers();
  • ApplicationListener感知全阶段:基于事件机制,感知事件。 一旦到了哪个阶段可以做别的事
    • @Bean@EventListener: 事件驱动
    • SpringApplication.addListeners(…)SpringApplicationBuilder.listeners(…)
    • META-INF/spring.factories
  • SpringApplicationRunListener:感知全阶段生命周期 + 各种阶段都能自定义操作; 功能更完善
    • META-INF/spring.factories
  • ApplicationRunner:感知特定阶段:感知应用就绪Ready。卡死应用,就不会就绪
    • @Bean
  • CommandLineRunner:感知特定阶段:感知应用就绪Ready。卡死应用,就不会就绪
    • @Bean

最佳实践:

  • 如果项目启动前做事: BootstrapRegistryInitializerApplicationContextInitializer
  • 如果想要在项目启动完成后做事:ApplicationRunnerCommandLineRunner
  • 如果要干涉生命周期做事SpringApplicationRunListener
  • 如果想要用事件机制ApplicationListener

2. 完整触发流程

9大事件触发顺序&时机

  1. ApplicationStartingEvent:应用启动但未做任何事情, 除过注册listeners and initializers.
  2. ApplicationEnvironmentPreparedEvent: Environment 准备好,但context 未创建.
  3. ApplicationContextInitializedEvent: ApplicationContext 准备好,ApplicationContextInitializers 调用,但是任何bean未加载
  4. ApplicationPreparedEvent: 容器刷新之前,bean定义信息加载
  5. ApplicationStartedEvent: 容器刷新完成, runner未调用
    =以下就开始插入了探针机制====
  6. AvailabilityChangeEventLivenessState.CORRECT应用存活; 存活探针
  7. ApplicationReadyEvent: 任何runner被调用
  8. AvailabilityChangeEventReadinessState.ACCEPTING_TRAFFIC就绪探针,可以接请求
  9. ApplicationFailedEvent :启动出错

在这里插入图片描述

感知应用是否存活了:可能植物状态,虽然活着但是不能处理请求。
应用是否就绪了:能响应请求,说明确实活的比较好。

3. SpringBoot 事件驱动开发

应用启动过程生命周期事件感知(9大事件)、应用运行中事件感知(无数种)。

  • 事件发布:ApplicationEventPublisherAware注入ApplicationEventMulticaster
  • 事件监听:组件 + @EventListener

在这里插入图片描述

事件发布者

@Service
public class EventPublisher implements ApplicationEventPublisherAware {

    /**
     * 底层发送事件用的组件,SpringBoot会通过ApplicationEventPublisherAware接口自动注入给我们
     * 事件是广播出去的。所有监听这个事件的监听器都可以收到
     */
    ApplicationEventPublisher applicationEventPublisher;

    /**
     * 所有事件都可以发
     * @param event
     */
    public void sendEvent(ApplicationEvent event) {
        //调用底层API发送事件
        applicationEventPublisher.publishEvent(event);
    }

    /**
     * 会被自动调用,把真正发事件的底层组组件给我们注入进来
     * @param applicationEventPublisher event publisher to be used by this object
     */
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }
}

事件订阅者

@Service
public class CouponService {

    @Order(1)
    @EventListener
    public void onEvent(LoginSuccessEvent loginSuccessEvent){
        System.out.println("===== CouponService ====感知到事件"+loginSuccessEvent);
        UserEntity source = (UserEntity) loginSuccessEvent.getSource();
        sendCoupon(source.getUsername());
    }

    public void sendCoupon(String username){
        System.out.println(username + " 随机得到了一张优惠券");
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据挖掘】时间序列教程【八】

4.4 时间混淆 我们先考虑一个简单的线性回归模型, 哪里 和是具有平均值的高斯过程00和自协方差 .现在,在不失去一般性的情况下,让我们假设 而那瓦尔

【UGUI控件全面解析】 教程专栏目录贴

🎬【UGUI控件全面解析】 教程专栏目录贴🐱‍🏍UGUI系列内容介绍🎁文章内容结构介绍 💯总结 🎬 博客主页:https://xiaoy.blog.csdn.net 🎥 本文由 呆呆敲代码的小Y 原创,…

“金九银十”和秋招通过率达 95% 的 Java 面试要点集锦

前言 这才刚刚进入 7 月,我就看到了许多朋友在焦急的准备“金九银十”跳槽面试,甚至很多即将毕业的大学生都在备战秋招,对于学历还算优秀的大学生来说,这是一次离大厂最近的机会,毕竟是应届毕业生,不会对技…

Selenium Wire编辑header破解反爬机制和访问限制

一、selenium Wire介绍 介绍 Selenium Wire扩展了Selenium的Python绑定,使您能够访问浏览器发出的底层请求。您已使用Selenium相同的方式编写代码,但是您获得了额外的api,用于检查请求和响应,并动态地对它们进行更改。&#xff08…

oracle 基础1

目录 Oracle表空间-创建 Oracle表空间-删除 Oracle常用用户 Oracle常用角色 Oracle用户创建 Oracle常用数据类型 Oracle表创建 Oracle增删改查 Oracle表常见约束 0.oracle手动开启方式 1.Oracle 表空间-创建 plsql登录system用户 新建sql窗口 创建表空间 2.Oracle表…

化亿级海量于秒级瞬间:大表关联计算提速

5G 时代,意味着数据通信将会拥有更高的速率、更大的容量和更低的时延。随着数据量的爆发式增长,对海量数据存储和实时分析成为数据淘金者的刚需,数据量暴增导致数据间的关联分析也越来越频繁。如何快速对数据进行分析,并获取其中有…

Jmeter接口测试参数化详解

目录 前言: RandomString函数 CSVRead函数 CSV Data Set Config配置元件 前言: 在进行接口测试时,参数化是一项重要的技术,可以帮助测试人员有效地模拟不同的场景和数据,增加测试用例的覆盖范围。JMeter提供了多种…

2023 年 10 大前端发展趋势

新技术的出现和老技术的淘汰让前端开发者们需要不断地学习和更新知识。特别是在经济不好的情况下,是否掌握新的技术很大程度决定着你是否被淘汰。 虽然应用程序试图将网站替代,但前端 Web 开发业务仍在快速变化和增长,前端开发人员的功能并没…

Debezium系列之:支持数据库存储系统,把ddl信息存储到数据库表中

Debezium系列之:支持数据库存储系统,把ddl信息存储到数据库表中 一、需求背景二、实现的效果三、核心参数四、创建存储ddl表五、创建采集表六、完整配置七、提交connector八、插入数据九、查看ddl数据十、修改表结构十一、清空存储ddl表十二、总结和延展一、需求背景 目前deb…

基于transformer的人群计数论文汇总

文章目录 2022TransCrowd: weakly-supervised crowd counting with transformersAn End-to-End Transformer Model for Crowd Localization 参考 2022 TransCrowd: weakly-supervised crowd counting with transformers code: https://github.com/dk-liang/TransCrowd 摘要&a…

达梦数据库性能分析

目录 数据库常用性能分析方法... 3 一、服务器监控... 3 1、cpu监控... 3 2、内存... 3 3、swap内存... 3 4、磁盘... 4 5、网络监测... 4 二、数据库实例监控... 6 1、v$sessions. 6 2、慢sql、阻塞、锁... 7 3、内存监控... 10 4、monitor监控工具使用及开启sql日…

五年Java学习心路历程

五年Java学习心路历程 从大学毕业到工作的过程中,我度过了五年学习Java的岁月。从基础语法到各种细节技术再到分布式和微服务架构,经历了许多的挑战与成长。接下来,我将详细记录这段心路历程,与大家分享学习Java的经验与感悟。 …

Java基础---String str=new String(“tang“)创建了几个对象

目录 典型回答 常量池基本概念 字符串常量池的结构 再看字面量和运行时常量池 intern 还是创建了几个对象 intern的正确用法 典型回答 创建的对象数应该是1个或者2个如果常量池中存在,则直接new一个对象如果常量池不存在,则在常量池中创建一个对象…

KubeEdge官方示例运行成功_Counter Demo 计数器

运行KubeEdge官方示例_Counter Demo 计数器 KubeEdge Counter Demo 计数器是一个伪设备,用户无需任何额外的物理设备即可运行此演示。计数器在边缘侧运行,用户可以从云侧在 Web 中对其进行控制,也可以从云侧在 Web 中获得计数器值,原理图如下…

前端web入门-移动web-day10

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 移动Web基础 手机模拟器 屏幕分辨率 视口 二倍图 适配方案 rem 适配方案 rem 媒体查询 rem – …

使用java生成mvt切片的方法

如何使用java生成geoserver的矢量切片供前端(mapbox等)调用 目录新的想法Java能为切片做什么如何生成切片如何转换xyz数据如何查询如何输出mvt格式给前端前端如何调用 目录 好久没发博客了,每日或忙碌、或悠闲、或喜或悲、时怅时朗&#xff…

访问学者怎样准备申请推荐信

作为访问学者,申请推荐信是非常重要的一步,它能够在您的申请过程中增加信誉度和竞争力。一个优秀的推荐信可以更好地展现您的学术能力、研究潜力和个人品质。以下是知识人网小编整理的关于如何准备申请推荐信的建议: 1. 确定推荐人&#xff1…

阿里云OSS上传文件工具类

个人主页:金鳞踏雨 个人简介:大家好,我是金鳞,一个初出茅庐的Java小白 目前状况:22届普通本科毕业生,几经波折了,现在任职于一家国内大型知名日化公司,从事Java开发工作 我的博客&am…

20本期刊影响因子上涨,7月SCI/SSCI/AHCI/EI刊源表已更新!

2023年7月SCI/SSCI/AHCI/EI期刊目录更新 2023年6月28日发布的最新《期刊引证报告》中,我处合作期刊中,7月刊源表有20本期刊影响因子上涨,同时新增多本快刊! 重磅!2023年JCR正式发布(附影响因子名单下载&a…

[github-100天机器学习]day2 simple linear regression

https://github.com/LiuChuang0059/100days-ML-code/blob/master/Day2_SImple_Linear_regression/README.md 简单线性回归 使用单一特征预测响应值。基于自变量X来预测因变量Y的方法,假设两者线性相关,寻找一种根据特征或自变量X的线性函数来预测Y。 目…