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

Spring ApplicationEventPublisher 事件发布

ApplicationEventPublisher

ApplicationEventPublisher是一个事件发布器,我们可以通过ApplicationContext来发布一个相应的事件
主要涉及到 事件定义、事件发布、事件订阅 三个模块

demo

事件

需要继承org.springframework.context.ApplicationEvent

/*** 定义我的事件*/
public class MyEvent extends ApplicationEvent {private String msg;public MyEvent(String msg) {super(msg);this.msg = msg;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}

发布

使用applicationEventPublisher发布事件即可

/*** 发布方** @author * @since 2024/12/4 20:30*/
@Component
public class MyPublisher implements ApplicationEventPublisherAware {private ApplicationEventPublisher applicationEventPublisher;private int id = 0;/*** 起了个定时任务,用来测试事件发布*/@Scheduled(cron = "*/30 * * * * ?")public void loop() {publish();}public void publish() {System.out.println("publish event. id: " + id);applicationEventPublisher.publishEvent(new MyEvent("new event " + id + " at " + System.currentTimeMillis()));id++;}@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher = applicationEventPublisher;}
}

订阅

实现org.springframework.context.ApplicationListener,注入到spring容器中。在泛型中指定需要监听的事件类型

/*** 订阅方*/
@Component
public class MyListener implements ApplicationListener<MyEvent> {@Overridepublic void onApplicationEvent(MyEvent event) {System.out.println("receive a event. msg : " + event.getMsg());}
}

测试结果:

publish event. id: 0
receive a event. msg : new event 0 at 1733368770009
publish event. id: 1
receive a event. msg : new event 1 at 1733368800008
publish event. id: 2
receive a event. msg : new event 2 at 1733368830011
publish event. id: 3
receive a event. msg : new event 3 at 1733368860007

其他事件监听方式

使用注解@EventListener

@Component
public class MyListener2 {@EventListenerpublic void onApplicationEvent(MyEvent event) {System.out.println("receive a event. msg : " + event.getMsg());}
}

其他

  1. 整个发布流程是同步的还是异步的?
    默认同步的。发布方和订阅方共用一个线程。
// 发布public void publish() {id++;System.out.printf("publish event start. id: %s. threadName: %s %n", id, Thread.currentThread().getName());applicationEventPublisher.publishEvent(new MyEvent("new event " + id + " at " + System.currentTimeMillis()));System.out.printf("publish event start. id: %s. threadName: %s %n", id, Thread.currentThread().getName());}// 订阅@EventListenerpublic void onApplicationEvent(MyEvent event) throws InterruptedException {sleep(5000);System.out.printf("receive a event. msg : %s. threadName: %s %n", event.getMsg(), Thread.currentThread().getName());}// 测试结果
// publish event start. id: 1. threadName: scheduled-task-thread2 
// receive a event. msg : new event 1 at 1733369970012. threadName: scheduled-task-thread2 
// publish event start. id: 1. threadName: scheduled-task-thread2
  1. 如何异步消费事件
    给订阅方上增加@Async注解,这样需要每次增加订阅方都增加注解
  2. 如何保证消费顺序
    当一个事件有多个消费者时,如果需要保证消费次序,可以使用注解@Order
  3. MQ和spring event的区别
    MQ更适合于应用级别的解耦,而spring event适用于应用内的解耦,更轻量
    相对MQ而言,spring event在系统故障时,由于数据是存在内存,会发生数据丢失
  4. 适用场景
  • 业务逻辑解耦。例如用户下单成功后,会触发库存减少、订单创建、支付请求等动作
  • 异步执行。适用于一些发布端不需要关心消费端如何处理,或异步线程不需要堵塞主线程的场景。如日志打印
http://www.jsqmd.com/news/33593/

相关文章:

  • NOIP模拟赛20251106 T4 CF1270H
  • 详细介绍:电阻的分类与应用
  • 题解:CF2121E Sponsor of Your Problems
  • wepoc Nuclei 漏洞扫描器图形界面工具
  • Python实现数据可视化用Matplotlib轻松创建专业级图表 - 指南
  • Python因果分析选哪个?六个贝叶斯推断库实测对比(含代码示例)
  • 题解:CF2121B Above the Clouds
  • 实用指南:学习日报 20251007|深度解析:基于 Guava LoadingCache 的优惠券模板缓存设计与实现
  • 选择 Tita 新绩效一体化的 5 大理由
  • NOIP模拟赛20251106 T3
  • 20251106周四日记
  • 学习:初学BP
  • 2025年上海防水补漏TOP5最新评测:从屋顶到地下室,全场景解决
  • 线段树维护区间历史信息和为例的复杂信息维护同标记下传设计技巧简记
  • 每日总结(三)
  • DFS 序
  • 重组蛋白纯化标签科普:从His到SUMO、Avi的全面解析
  • 2025.11.6
  • 飞牛nas播放卡顿的解决方案
  • 第三十五篇
  • 使用LLaMA Factory微调模型笔记
  • 25.11.6联考题解
  • Linux驱动学习(一)---Ubuntu-helloworld驱动编译
  • 2025/11/3 ~ 2025/11/9 做题笔记 - sb
  • 利用Google Dork挖掘敏感文件setup.sh的技术解析
  • 11.6 程序员的修炼之道:从小工到专家 第四章 注重实效的偏执 - GENGAR
  • 2025.11.6~?
  • 详细介绍:自建数字资源库:技术架构全解析
  • 人工智能价值权衡的元理论:三值纠缠与文明演进的动力学框架
  • golang面经——内存相关模块 - 详解