SpringBoot基础--06事件和监听器

springboot事件推送 案例:用户注册成功之后往往会有额外的反复修改的不影响注册事件的事件,比如:发送短信/邮件/积分/优惠券等.上面这四种事件因注册事件的成功而发生,但是事件本身的成功与否不应该影响注册事件本身,而且这些事件在项目的整个周期中存在反复添加修改删除,所以这些事件与注册事件不应该耦合在一起. 解决上面的问题除了采用MQ的方式外,spring提供了一种广播-监听的方式来实现.当注册事件成功之后,广播一天消息:xxx注册成功;众多监听者听到这条广播时,对这条广播有兴趣的会立刻回应,给XXX一张优惠券/给XXX200积分; 阅读详情

核心原理

事件和监听器

生命周期监听器

自定义SpringApplicationRunListener来监听事件;

  1. 编写SpringApplicationRunListener 实现类
  2. 在 META-INF/spring.factories 中配置 org.springframework.boot.SpringApplicationRunListener=自己的Listener,还可以指定一个有参构造器,接受两个参数(SpringApplication application, String[] args)

执行顺序

Listener先要从 META-INF/spring.factories 读到

  1. 引导: 利用 BootstrapContext(启动上下文) 引导整个项目启动
  • starting:
    • 应用开始,SpringApplication的run方法一调用,只要有了 BootstrapContext 就执行
    • 触发ApplicationStartingEvent事件
  • environmentPrepared:
    • 环境准备好(把启动参数等绑定到环境变量中),但是ioc还没有创建;【调一次】
    • 触发ApplicationEnvironmentPreparedEvent事件
  1. 启动:
  • contextPrepared:
    • ioc容器创建并准备好,但是sources(主配置类)没加载。并关闭引导上下文;组件都没创建 【调一次】
    • 触发ApplicationContextInitializedEvent事件
  • contextLoaded:
    • ioc容器加载。主配置类加载进去了。但是ioc容器还没刷新(我们的bean没创建)。
    • 触发ApplicationPreparedEvent事件
  • started:
    • ioc容器刷新了(所有bean造好了),但是 runner 没调用。
    • 触发AvailabilityChangeEvent事件(存活探针)
  • ready:
    • ioc容器刷新了(所有bean造好了),所有 runner 调用完了。
    • 触发AvailabilityChangeEvent事件事件(就绪探针)
  1. 运行
  • 以前步骤都正确执行,代表容器running。
  1. 启动失败(以上步骤仍一失败)
  • 若应用启动失败则调用该方法
  • 触发ApplicationFailedEvent事件

生命周期监听器

package com.atli.springbootweb;

public class MyAppListener implements SpringApplicationRunListener {
    @Override
    public void starting(ConfigurableBootstrapContext bootstrapContext) {
        System.out.println("应用启动");
    }

    @Override
    public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
        System.out.println("环境准备就绪");
    }

    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("ioc容器创建成功");
    }

    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("ioc容器主配置类加载成功(ioc容器加载完成)");
    }

    @Override
    public void started(ConfigurableApplicationContext context, Duration timeTaken) {
        System.out.println("ioc容器中所有bean创建成功(启动完成,还未初始化)");
    }

    @Override
    public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
        System.out.println("ioc容器初始化完成(bean建立完成且runner调用完成)");
    }

    @Override
    public void failed(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("应用启动失败");
    }
}

声明周期监听器配置文件

# resources/META-INFO/spring.factories
org.springframework.boot.SpringApplicationRunListener=com.atli.springbootweb.MyAppListener

事件触发时机

回调监听器
  • BootstrapRegistryInitializer:
    • 感知特定阶段:感知引导初始化
    • 创建引导上下文bootstrapContext的时候触发。
    • 场景:进行密钥校对授权。
    • 通过配置META-INF/spring.factories使用
    • 或者在main中配置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标记使用
完整的九大事件触发顺序
  1. ApplicationStartingEvent:
  • 应用启动但未做任何事情, 除过注册listeners and initializers.
  1. ApplicationEnvironmentPreparedEvent:
  • Environment 准备好,但context 未创建.
  1. ApplicationContextInitializedEvent:
  • ApplicationContext 准备好,ApplicationContextInitializers 调用,但是任何bean未加载
  1. ApplicationPreparedEvent:
  • 容器刷新之前,bean定义信息加载
  1. ApplicationStartedEvent:
  • 容器刷新完成, runner未调用
    =以下就开始插入了探针机制====
  1. AvailabilityChangeEvent:
  • LivenessState.CORRECT应用存活; 存活探针
  1. ApplicationReadyEvent:
  • 任何runner被调用
  1. AvailabilityChangeEvent:
  • ReadinessState.ACCEPTING_TRAFFIC就绪探针,可以接请求
  1. ApplicationFailedEvent :
  • 启动出错
事件驱动开发
  • 使用该技术,利用应用启动过程中对生命周期事件和应用运行中事件的感知可以实现订阅-发布模式
  • 使用该模式可以实现对修改关闭,对扩展开放的设计原则
  1. 创建一个事件类继承ApplicationEvent类,并在构造器中调用super的构造器方法,传入该事件信息
  2. 创建一个事件发布类,实现ApplicationEventPublisherAware接口,实现该接口的setApplicationEventPublisher方法,创建一个成员变量来接收实现方法的形参。编写一个发布事件的方法,调用applicaitonEventPublisher的publishEvent方法

事件发布者

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

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

    /**
     * 利用多态实现可以发送所有类型的事件
     * @param event
     */
    public void sendEvent(ApplicationEvent event) {
        //调用底层API发送事件
        applicationEventPublisher.publishEvent(event);
    }
}

事件订阅者

@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 + " 随机得到了一张优惠券");
    }
}

自定义事件

public class LoginSuccessEvent extends ApplicationEvent{
  /**
   * @param source 代表登录成功的对象,自己写一个类,比如包括用户名之类的
   */
  public LoginSuccessEvent(UserEntity source){
    super(source);
  }
}

事件触发者

@RestController
public class UserController{
  @Autowired
  EventPublisher enventPublisher

  //发送事件
  enventPublisher.sendEvent(new LoginSuccessEvent(new UserEntity("1","li","18")))
}
【SpringBoot源码】SpringBoot监听机制分析 一、简介接下来我们分析下SpringBoot的机制的源码。二、SpringBoot事件监听机制。 阅读详情

相关推荐

【玩转SpringBoot】通过事件机制参与SpringBoot应用的启动过程

生命周期和事件监听一个应用的启动过程和关闭过程是归属到“生命周期”这个概念的范畴。典型的设计是在启动和关闭过程中会触发一系列的“事件”,我们只要监听这些事件,就能参与到这...

李新杰的优快云 826

Spring Boot - Application Events 的发布顺序_AvailabilityChangeEvent

Spring Boot 的广播机制是基于观察者模式实现的,它允许在 Spring 应用程序中发布和监听事件。这种机制的主要目的是为了实现解耦,使得应用程序中的不同组件可以独立地改变和复用逻辑,而无需直接进行通信。在 Spring Boot 中,事件发布和监听的机制是通过以及事件发布者()来实现的。其中,ApplicationEvent 是所有自定义事件的基础,自定义事件需要继承自它。是监听特定事件并做出响应的接口,开发者可以通过实现该接口来定义自己的监听器。事件发布者(通常由 Spring 的。

小工匠 7852

【高级篇】进阶提升SpringBoot+Quartz实战---监听器配置

本篇博客主要是分享,高级篇Quartz的配置,嗨皮的开发与工作

知识改变命运,ヾ(◍°∇°◍)ノ゙【求关注】 1413

SpringBoot生命周期

SpringBoot应用的生命周期,整体上可以分为SpringApplication初始化阶段、SpringApplication运行阶段、SpringApplication结束阶段、SpringBoot应用退出四个阶段。

SpringBoot应用最佳实践 1万+

带挂牵引车前向运动模型推导及仿真实现

牵引车-半挂车的车辆结构与普通的车辆相比增加了一个半挂车,它们之间通过鞍座相连接,为了分析半挂牵引车运动过程中的位姿和状态,本文将基于车辆的机械结构建立对应的运动学模型,该模型基于以下假设: 车辆行驶过程中,道路平坦且无凸凹; 车辆低速行驶,且运行过程中车身无侧倾和俯仰运动; 车辆行驶过程中,轮胎无形变,无侧向滑动,且无侧向力; 牵引车和半挂车均满足阿克曼转向几何原理; 牵引车与半挂车不会发现折叠。

jianmo的博客 3182

海思Hi3516CV610--SPI NAND Flash移植实战:从手册到驱动的完整适配

本文详细介绍了海思Hi3516CV610芯片上SPI NAND Flash的移植实战,包括从手册解读到驱动适配的完整流程。以GD5F2GM7UEYIGR Flash为例,重点讲解了关键参数确认、模式选择、时序配置以及U-Boot和Linux内核驱动的具体实现步骤,帮助开发者快速完成Flash移植工作。

weixin_29158413的博客 447

SpringBoot之事件监听

这个事件在当 Spring 应用上下文(ApplicationContext)准备好了,并且应用初始化器(ApplicationContextInitializers)已经被调用,在 bean 的定义(bean definitions)被加载之前发送。这个事件在当已知要在上下文中使用 Spring 环境(Environment)时,在 Spring 上下文(context)创建之前发送。这个事件紧随上个事件之后发送,状态:ReadinessState.CORRECT,表示应用已处于活动状态。

zhzjn的博客 579

Ubuntu 22.04 局域网安装GitLab

下面直接给你一份。

u013250861的博客 667

SpringBoot中就绪探针和存活探针

文章目录1.介绍2.Kubernetes探针3.就绪探针和存活探针在Actuator3.1.就绪和活跃状态转换4. 管理应用程序可用性4.1. 更新可用性状态4.2.监听变化 1.介绍 本篇中将介绍 Spring Boot 2.3 如何与 Kubernetes 探针集成以创建更愉快的云原生体验。 首先,将从 Kubernetes 探针的一些背景开始。 然后,看看 Spring Boot 2.3 如何支持这些探针。 2.Kubernetes探针 当使用 Kubernetes 作为我编排平台时,每个节点中的 k

盲目的拾荒者的博客 1万+

告别两个电源模块!用UCD3138+四开关Buck-Boost,一个电路搞定电池充放电(附原理图分析)

本文详细介绍了采用UCD3138数字控制器和四开关Buck-Boost拓扑的双向DC/DC变换器设计,实现单一电路完成电池智能充放电管理。该方案显著降低BOM成本和PCB面积,提升系统效率至96.2%,适用于UPS、通信基站和储能系统,具有高效、紧凑和成本优势。

weixin_30256901的博客 397

Apollo和autoware规划算法代码ros移植-路径规划可跑工程分享

Apollo6.0规划核心代码移植到Ros工程,可编译移植分享

weixin_39735688的博客 8508

SpringBoot核心原理之事件和监听器(生命周期监听、事件触发、监听器、自定义事件发布和订阅)和配置类和Bean加载的时机

场景:监听应用从创建到销毁的整个生命周期。这样可以在应用启动之前,或启动之后做一些操作 用于事件发布。在生命周期的各个重要环节,都会将事件进行广播,如果我们对那个事件比较关系,可以继续监听自定义示例如下: MyAppListener.java src\main\resources\META-INF\spring.factories 启动springBoot应用,打印如下: 1.2 生命周期全流程 源码分析如下: 2. 事件触发时机 2.1 各种回调监听器 BootstrapRegistryInitiali

Bulut0907 2965

生成自定义工具栏

我们生成了和VBA时代几乎一样的常用的工具栏。用WPF也可以完成以后的插件开发,界面控件编写基本靠自己绘画,还有用代码去控制,代码结构像HTML,做过网站的应该可以很快入手。其它后台C#代码除了对控件代码的控制外,和WinForm基本相同,但目前来看用WPF是生成自定义工具栏的较好的办法。当然,你也可以在工具栏命令中调用WinForm程序,对Coreldraw进行操作,这也应该是比较高效的办法,下次会讨论。资源的加入是本次调试的难点之一,我们的目标是让图片资源嵌入到程序中去,不必去电脑文件目录去调用;

力先生C#程序开发 1374

深入学习SpringBoot中的应用事件和监听器

1 引言 在项SpringBoot目中我们经常需要一些监听器,通过监听一些事件做出相应的反应,并确保组件在生命周期内正常运行。比如上下文加载监听器。 ContextLoaderListener监听ServletContextEvent用于确定何时初始化和销毁应用上下文,ContextRefreshListener监听应用上下文刷新事件ContextRefreshedEvent。有时根据业务需求,作为开发人员我们也需要定义自己的事件,比如自定义用户注册、更新和删除事件,并做出相应的处理。 例如分布式组件zoo

heshengfu1211的博客 1368

SAP-ABAP:SAP HANA性能神器FDA:是极速查询的引擎,也是CPU过载的元凶

在SAP S/4HANA的世界里,有一个被ABAP开发者们既爱又怕的特性——Fast Data Access(FDA),它能将性能提升百倍,也能让CPU瞬间飙升。本文将带您全面解剖这一核心机制。

baidu_35680696的博客 849

Python 实战:手语翻译系统——从视频到文本的智能转换

今天,我们用 Python 构建了一个。

Echo_Wish 344

SpringBoot-事件监听的4种实现方式

springboot进行事件监听有四种方式:1.手工向ApplicationContext中添加监听器2.将监听器装载入spring容器3.在application.properties中配置监听器4.通过@EventListener注解实现事件监听讲到事件监听,这里我们说下自定义事件和自定义监听器类的实现方式:自定义事件:继承自ApplicationEvent抽象类,然后定义自己的构造器自定义监...

ignorewho的博客 3万+

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

06. Spring中的事件监听器

一 概念 1. Spring中的事件监听 在一个Spring容器中,我们可以发送消息给Spring容器,容器收到消息后自动接受消息并进行处理 事件监听主要有两部分组成,一个是事件源,另一个是监听事件并处理的对象 使用的时候,我们只需要自定义事件继承事件对象ApplicationEvent,自定义监听器实现监听器ApplicationListener,并将监听器注册到Spring容器中即可 1.1 事件 Spring事件对象为ApplicationEvent,继承自ObjectEvent public abs

m0_46836425的博客 529

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

springboot进行事件监听有四种方式

springboot进行事件监听有四种方式: 1.手工向ApplicationContext中添加监听器 2.将监听器装载入spring容器 3.在application.properties中配置监听器 4.通过@EventListener注解实现事件监听 讲到事件监听,这里我们说下自定义事件和自定义监听器类的实现方式: 自定义事件:继承自ApplicationEvent抽象类,然后定义自己的构...

qianxiaopeng的专栏 2453

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

springboot中的事件

官网对springboot事件的描述 springboot中事件的发布顺序(发送优先级从高到底) ApplicationStartingEvent在运行开始时发送 ,但在进行任何处理之前(侦听器和初始化程序的注册除外)发送 ApplicationEnvironmentPreparedEvent当被发送Environment到中已知的上下文中使用,但是在创建上下文之前 ApplicationCon...

xingfeichen的博客 1070

SpringBoot中使用监听器

去实现ApplicationListerner 需不需要异步自己看着办。第三步简单实用了@EventListener注解 如果不用就需要这么做。2.通过ApplicationEventPublisher 发布事件。3.通过监听器订阅事件。

tiantiantbtb的博客 1468

SpringBoot源码分析之-启动流程分析三(监听器SpringApplicationRunListener)

目录前言观察者模式run方法中出现的地方 前言 上一篇SpringBoot源码分析之-启动流程分析二(run方法) 简单分析了的run流程 这一篇主要分析一下监听器 SpringApplicationRunListener 观察者模式 class SpringApplicationRunListeners { //监听器集合 private final List<SpringApplicationRunListener> listeners; SpringApplicationRu

xc的博客 471

SpringBoot ~ 过滤器、监听器、Servlet

​ SpringBoot为整合过滤器、监听器、Servlet,定义了3个基本的组件,分别使用@WebServlet、@WebFilter、@WebListener进行标记 项目入口类添加@ServletComponentScan实现对Filter、Listener、Servlet的扫描 @SpringBootApplication @ServletComponentScan public class Demo01Application { public static void main(.

简单点 175

Spring Boot 事件监听机制实战【自定义 Spring Boot 事件监听】

事件监听器实现了 ApplicationLister 接口,泛型为 ApplicationEvent,因为要监听事件,所以必须按照 Spring 的规则来,onApplicationEvent 方法就是监听到的事件,在这里可以完成业务逻辑处理,因为事件监听器需要加入Spring IOC 容器中才能生效,因此 MyListener 使用了 @Component 注解。上一篇我们分析了 Spring Boot 事件监听的原理,本篇我们来自定义实现自己的监听器。欢迎提出建议及对错误的地方指出纠正。

weixin_42118323的博客 847

SpringBoot事件监听的4种实现方式

springboot进行事件监听有四种方式: 手工向ApplicationContext中添加监听器 将监听器装载入spring容器 在application.properties中配置监听器 通过@EventListener注解实现事件监听 讲到事件监听,这里我们说下自定义事件和自定义监听器类的实现方式: 自定义事件:继承自ApplicationEvent抽象类,然后定义自己的构造器 自定义监听:实现ApplicationListener<T&

gp_911014的博客 446

onreadystatechange 事件一共会被触发几次_「玩转SpringBoot」通过事件机制参与SpringBoot应用的启动过程...

转载:https://mp.weixin.qq.com/s/mB8pN0o2j08Kq8zXXPCFZQ生命周期和事件监听一个应用的启动过程和关闭过程是归属到“生命周期”这个概念的范畴。典型的设计是在启动和关闭过程中会触发一系列的“事件”,我们只要监听这些事件,就能参与到这个过程中来。要想监听事件,首先得有事件监听器,就是常说的Listener。下面就是Spring提供的监听器,如下图01:按规定...

weixin_39640762的博客 164
上一篇: SpringBoot基础--05基础特性
下一篇: java函数式编程基础
sisyphoslee
博客等级 码龄7年 942粉丝 142原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值