SpringEvent事件通知机制

“Spring Event” 是 Spring 框架通过事件驱动的编程模型来处理应用程序中的事件。开发者可以定义自己的事件,然后在应用程序中触发这些事件。Spring 框架提供了用于发布和监听事件的机制,以实现松散耦合的组件间通信。

有两个核心组件:

  • 事件
  • 监听器

案例代码:
1.创建事件

@Getter
public class UserRegisterEvent extends ApplicationEvent {private User user;public UserRegisterEvent(Object source, User user) {super(source);System.out.println(source);this.user = user;}
}

2.创建监听器

@Slf4j
@Component
public class UserRegisterListener {@Autowiredprivate UserBackpackService userBackpackService;@EventListener(classes = UserRegisterEvent.class)public void sendCard(UserRegisterEvent event) {User user = event.getUser();System.out.println("给"+user.getId()+"发改名卡...");}
}

3.发布事件

@Service
public class UserServiceImpl implements UserService {@AutowiredApplicationEventPublisher applicationEventPublisher;@Overridepublic void register(User user) {userDao.save(user);applicationEventPublisher.publishEvent(new UserRegisterEvent(this, user));}
}

4.结果

com.cong.common.user.service.impl.UserServiceImpl@16cc5e5111009发改名卡...

@EventListener 和 @TransactionalEventListener 是 Spring Framework 中用于处理事件的两个注解,它们之间主要的区别在于对事务的处理方式。

总结一下:

@EventListener:

事件监听器和发布事件方法默认是同步(同一个线程)执行,想让监听器异步执行,在监听器上加@Async注解(需要在启动类Application上使用@EnableAsync注解,引入对@Async的支持。)

  • value:用于指定监听的事件类型。可以是单个事件类型,也可以是一个事件类型数组。如果不提供该参数,则默认监听所有事件。
  • classes:与 value 参数类似,用于指定监听的事件类型。可以是单个事件类型,也可以是一个事件类型数组。与 value 不同的是,classes 是 @EventListener 注解的属性名称。
  • fallbackExecution:用于指定当事件处理方法无法执行时是否执行备用方法。默认值为 true,表示如果事件处理方法无法执行,则执行备用方法;设置为 false 表示如果事件处理方法无法执行,则不执行备用方法。
  • condition:用于指定在何种条件下执行事件监听器方法。可以使用 SpEL 表达式来定义条件。如果条件求值为 false,则事件监听器方法不会执行。

在这里插入图片描述

@TransactionalEventListener:用于标记一个方法,表示它是一个事件监听器,并且该方法应该在事务的不同阶段进行调用。

  • value:用于指定监听的事件类型。可以是单个事件类型,也可以是一个事件类型数组。如果不提供该参数,则默认监听所有事件。
  • phase:指定要监听的事务阶段,可以是AFTER_COMMIT、AFTER_ROLLBACK或AFTER_COMPLETION。默认是AFTER_COMMIT。
  • fallbackExecution:用于指定当事务无法提交时是否执行事件监听器。默认值为 true,表示如果事务无法提交,则执行事件监听器;设置为 false 表示如果事务无法提交,则不执行事件监听器。
  • condition:用于指定在何种条件下执行事件监听器方法。可以使用 SpEL 表达式来定义条件。如果条件求值为 false,则事件监听器方法不会执行。

@EventListener和@TransactionalEventListener的使用场景比较,什么时候该用哪个

@EventListener:

事务处理:

  • 不会开启新的事务,事件监听器方法将在发布事件的同一事务中执行。
  • 如果事件监听器方法抛出异常,不会影响到发布事件的事务。

执行阶段:

  • 事件监听器方法默认在事务提交后(TransactionPhase.AFTER_COMMIT)执行。
  • 不支持指定执行阶段。

适用场景:

  • 适用于不需要事务支持的简单事件处理场景。
  • 当事件处理逻辑不依赖于事务,或者对事务没有特殊要求时。

@TransactionalEventListener:

事务处理:

  • 会开启新的事务,事件监听器方法在新的事务中执行。
  • 事件监听器方法的事务与发布事件的事务独立,互不影响。
  • 如果事件监听器方法抛出异常,该事务将回滚,影响到发布事件的事务。

执行阶段:

  • 可以指定事件监听器方法的执行阶段,包括事务提交前、事务提交后、事务回滚后等。
  • 支持更精细的事务控制。

适用场景:

  • 适用于需要事务支持的场景,例如,希望在新事务中执行,或者希望根据事务阶段执行不同的逻辑。
  • 当事件处理逻辑对事务有特殊要求时,例如需要在事务提交前执行某些操作。

总体建议:
如果事件处理逻辑简单,不需要事务支持,或者事务隔离不是关键考虑因素,可以选择使用 @EventListener。
如果事件处理逻辑需要事务支持,或者需要在事务的不同阶段执行不同的逻辑,可以选择使用 @TransactionalEventListener。
总之发布事件方法加了事务用@TransactionalEventListener,没加事务用@EventListener

MQ和SpringEvent两种对比,什么时候该用哪个

消息队列(MQ)和 Spring 事件机制(ApplicationEvent 和相关注解如 @EventListener)是两种不同的通信机制,它们各自有适用的场景和优势。以下是它们的对比和在何时选择使用哪个的一些建议:

MQ(消息队列):

分布式系统:

  • MQ 适用于分布式系统,可以实现异步、解耦、松散耦合的组件通信。
  • 当系统需要将不同服务或模块进行解耦,降低它们之间的直接依赖性时,可以使用消息队列。

持久性:

  • MQ 提供消息的持久性,消息可以被持久化到队列中,确保在消息发送和接收之间出现故障时消息不会丢失。
  • 当系统对消息的可靠性和持久性要求较高时,可以选择使用消息队列。

异步通信:

  • MQ 支持异步通信,生产者将消息发送到队列,而不需要等待消费者的响应。
  • 当系统需要异步处理,提高系统的吞吐量和响应性能时,可以使用消息队列。

消息传递的中间件:

  • MQ 是专门设计用于消息传递的中间件,有多种消息队列系统可供选择,如 RabbitMQ、Apache Kafka、ActiveMQ 等。
  • 当系统需要高度可配置和专门优化的消息传递机制时,可以选择适合的消息队列。

Spring 事件机制:

单体应用或微服务内部通信:

  • Spring 事件机制更适用于单体应用或微服务内部的组件通信,通过 Spring 的事件机制,不同组件之间可以进行解耦,但通信相对于 MQ 更为简单。
  • 当系统是一个相对较小规模的单体应用或内部微服务通信较为简单时,可以选择使用 Spring 事件机制。

松散耦合:

  • Spring 事件机制通过发布-订阅的方式实现组件之间的松散耦合。
  • 当系统中的组件需要解耦,但又不需要引入消息队列等复杂的中间件时,可以选择使用 Spring 事件机制。

同步通信:

  • Spring 事件机制是同步的,发布者会等待所有监听器执行完毕后再继续执行。这与 MQ 的异步通信有所不同。
  • 当系统中的组件之间需要同步通信,且不需要引入异步处理时,可以选择使用 Spring 事件机制。

简化配置和集成:

  • Spring 事件机制是 Spring 框架的一部分,可以方便地与其他 Spring 特性集成,且不需要引入额外的中间件。
  • 当系统中已经使用 Spring 框架,且通信需求较为简单时,可以选择使用 Spring 事件机制。

如何选择:
如果系统是一个分布式系统,需要异步、解耦、持久性、高可靠性的通信机制,可以考虑使用消息队列。
如果系统是一个单体应用或者微服务内部通信相对简单,需要简化配置和集成,可以考虑使用 Spring 事件机制。
在一些场景中,也可以同时使用两者,根据具体的通信需求选择合适的机制。
总的来说,选择 MQ 还是 Spring 事件机制取决于系统的规模、架构、通信需求和对可维护性的要求。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

红色旅游AR互动体验将景区推向更广泛的市场

AR技术的出现使得各展厅观众可以在虚拟和现实的层面进行互动,利用AR和VR技术,将展览地点扩展到特定的虚拟领域,实现了"无触觉"交互体验,增强现实技术和展馆的对接更加激发人们了解新事物的兴趣。 一、AR景区&#xff1a…

手把手教你实现贪吃蛇

> 作者简介:დ旧言~,目前大二,现在学习Java,c,c,Python等 > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:实现贪吃蛇 > 毒鸡汤:时间并不可真…

Flutter笔记:绘图示例 - 一个简单的(Canvas )时钟应用

Flutter笔记 绘图示例 - 一个简单的(Canvas )时钟应用 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_2855…

SOME/IP学习笔记2

1. SOME/IP 协议 SOME/IP目前支持UDP(用户传输协议)和TCP(传输控制协议), PS:UDP和TCP区别如下 TCP面向连接的,可靠的数据传输服务;UDP面向无连接的,尽最大努力的数据传输服务&…

Windows使用ssh远程连接(虚拟机)Linux(Ubuntu)的方法

步骤 1.Windows下载一个SSH客户端软件 要使用SSH连接,当然得先有一个好用的客户端软件才方便。 我这里使用的是WindTerm,一个开源免费的SSH连接工具,用什么软件不是重点。 这里默认你已经生成过SSH的密钥了,如果没有&#xff0c…

OpenHarmony 开发者论坛正式上线,盖楼赢惊喜好礼~

你,是否曾遇到 OpenHarmony 开发难题,却不知找谁解答? 你,是否曾想分享 OpenHarmony 技术,但没有一个官方投稿平台? 你,是否想加入火热的 OpenHarmony 开源项目,却不知如何参与和贡…

【Python大数据笔记_day07_hive中的分区表、分桶表以及一些特殊类型】

分区表 分区表的特点/好处:需要产生分区目录,查询的时候使用分区字段筛选数据,避免全表扫描从而提升查询效率 效率上注意:如果分区表在查询的时候呀没有使用分区字段去筛选数据,效率不变 分区字段名注意:分区字段名不能和原有的字段名重复,因为分区字段名要作为字段拼接到表后…

新版软考高项试题分析精选(三)

请点击↑关注、收藏,本博客免费为你获取精彩知识分享!有惊喜哟!! 1、项目整体管理要综合考虑项目各个相关过程,围绕整体管理特点,以下说法中,( )是不正确的。 A.项目的…

MDM如何配置数据审批功能

MDM基础数据平台是进行清洗和治理企业的主数据,使企业的主数据具有唯一性、准确性、一致性、及时性,通过主数据数据清洗功能将错误数据和重复数据进行清洗,从而保证企业数据能够做到以上那几点,然后再分发至下游系统,使…

ebSocket connection to ‘wss://xxx.xxxxxxx.xxx/‘ failed:

目录 1:网络连接问题:检查您是否已连接到互联网,您的网络是否稳定。您还可以尝试重置您的Internet连接或切换到另一个网络。 排除方法:直接打开个网址就知道了,这应该不用教了吧 2:防火墙或代理设置&…

【MySQL】对表结构进行增删查改的操作

表的操作 前言正式开始建表查看表show tables;desc xxx;show create table xxx; 修改表修改表名 rename to对表结构进行修改新增一个列 add 对指定列的属性做修改 modify修改列名 change 删除某列 drop 删除表 drop 前言 前一篇讲了库相关的操作,如果你不太懂&…

前端JS解构数组对象

// 3. 对象数组解构const arr [{username: 小明,age: 18,agw:19},{username: 小ha,age: 18,agw:19}]arr.map(item>item.age)//js结构数组对象console.log( arr.map(item>{return {aaa:item.age,bbb:item.username}}))