Spring Event + DDD = 王炸!!下

简介: Spring Event + DDD = 王炸!!下

2.3.基于异步事件处理

@Async是Spring框架中的一个注解,用于将一个方法标记为异步执行。使用该注解,Spring将自动为该方法创建一个新线程,使其在后台异步执行,不会阻塞主线程的执行。

在具体应用中,使用@Async可以大大提升应用的并发处理能力,使得系统能够更快地响应用户请求,提高系统的吞吐量。

@Async 和 @EventListener 或 @TransactionEventListener 注解在一起使用时,会产生异步的事件处理器。使用这种组合的方式,事件处理器会在单独的线程池中执行,以避免阻塞主线程。这种方式在需要处理大量事件或者事件处理器耗时较长的情况下非常有用,可以有效提高应用的性能和可伸缩性。同时,Spring 框架对这种方式也提供了完善的支持,可以方便地使用这种方式来实现异步事件处理。

下面是一个简单的示例代码,演示了如何在 Spring 中使用 @Async 和 @EventListener 一起实现异步事件处理:

@Component
public class ExampleEventListener {
    @Async
    @EventListener
    public void handleExampleEvent(ExampleEvent event) {
        // 在新的线程中执行异步逻辑
        // ...
    }
}

在这个示例中,ExampleEventListener 类中的 handleExampleEvent 方法使用了 @Async 和 @EventListener 注解,表示这个方法是一个异步事件监听器。当一个 ExampleEvent 事件被触发时,这个方法会被异步地执行。在这个方法中,可以执行任何异步的逻辑处理,比如向队列发送消息、调用其他服务等。

备注:在使用 @Async 时,需要根据业务场景对线程池进行自定义,以免出现资源不够的情况(Spring 默认使用单线程处理@Async异步任务)

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

4. 场景分析

综上所述,当领域事件发出来之后,不同的注解会产生不同的行为,简单汇总如下:


@EventListener @TransactionEventListener
无 @Async 顺序、同步执行 事务提交后、同步执行
有 @Async 顺序、异步执行 事务提交后、异步执行

4.1. @EventListener

特点:

  1. 顺序执行。调用 publish(Event) 后,自动触发对 @EventListner 注释方法的调用
  2. 同步执行。使用主线程执行,方法抛出异常会中断调用链路,会触发事务的回归

应用场景:

  1. 事务消息表。在同一事务中完成对业务数据和消息表的修改
  2. 业务验证。对业务对象进行最后一次验证,如果验证不通过直接抛出异常中断数据库事务
  3. 业务插件。在当前线程和事务中执行插件完成业务扩展

4.2. @TransactionEventListener

特点:

  1. 事务提交后执行。调用 publish(Event) 时,只是向上下文中注册了一个回调器,并不会立即执行;只有在事务提交后,才会触发对 @TransactionEventListner 注释方法的调用
  2. 同步执行。使用主线程执行,方法抛出异常会中断调用链路,当不会回归事务(事务已提交,没有办法进行回归)

应用场景:

  1. 数据同步。事务提交后,将变更同步到 ES 或 Cache
  2. 记录审计日志。只有在业务变更成功更新到数据库时才进行记录

备注:@TransactionEventLisnter 必须在事务上下文中,脱离上下文,调用不会生效

4.3. @EventListener + @Async

特点:

  1. 顺序执行。调用 publish(Event) 后,自动触发对 @EventListner 注释方法的调用
  2. 异步执行。使用独立的线程池执行任务,方法抛出异常对主流程没有任何影响

应用场景:

  1. 记日志明细日志,辅助排查问题

4.4. @TransactionEventListener + @Async

特点:

  1. 事务提交后执行。调用 publish(Event) 时,只是向上下文中注册了一个回调器,并不会立即执行;只有在事务提交后,才会触发对 @TransactionEventListner 注释方法的调用
  2. 异步执行。使用独立的线程池执行任务,方法抛出异常对主流程没有任何影响

应用场景:异步处理。记录操作日志,异步保存数据等 备注:@TransactionEventLisnter 必须在事务上下文中,脱离上下文,调用不会生效

5. 小结

领域事件的落地,不仅需要强大的设计能力,还需要与之匹配的基础设施。Spring 作为最常用的框架,基于发布订阅实现了完整的一套 Event 管理机制。工具在手是否能根据业务场景选择合适的解决方案就成了研发的职责,简单思考以下组合适用场景是什么:

  1. @EventListener
  2. @TransactionEventListener
  3. @EventListener + @Async
  4. @TransactionEventListener + @Async


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
7月前
|
Java Spring
Spring Event陷阱重重,我为何含泪放弃?
网络上比较推崇使用Spring Event 优雅的实现观察者模式。我在调研后也确实觉得这种方式能实现业务逻辑上的解耦,但线上的一次事故,让我意识到 Spring Event远远没有那么简单。
494 1
Spring Event陷阱重重,我为何含泪放弃?
|
11月前
|
Java Spring
深入理解Spring IOC之扩展篇(十)、SpringBoot中重要event介绍,顺便简单讲下SB的启动流程(二)
深入理解Spring IOC之扩展篇(十)、SpringBoot中重要event介绍,顺便简单讲下SB的启动流程(二)
77 0
|
11月前
|
XML Java 数据格式
深入理解Spring IOC之扩展篇(九)、SpringBoot中重要event介绍,顺便简单讲下SB的启动流程(一)
深入理解Spring IOC之扩展篇(九)、SpringBoot中重要event介绍,顺便简单讲下SB的启动流程(一)
95 0
|
11月前
|
设计模式 缓存 Java
深入理解Spring IOC之扩展篇(七)、Spring中的event以及自定义event
深入理解Spring IOC之扩展篇(七)、Spring中的event以及自定义event
81 0
|
12月前
|
消息中间件 存储 架构师
【首席架构师看Event Hub】Kafka深挖 -第2部分:Kafka和Spring Cloud Stream
【首席架构师看Event Hub】Kafka深挖 -第2部分:Kafka和Spring Cloud Stream
|
12月前
|
消息中间件 缓存 前端开发
「首席看Event Hub」如何在您的Spring启动应用程序中使用Kafka
「首席看Event Hub」如何在您的Spring启动应用程序中使用Kafka
|
12月前
|
消息中间件 架构师 Java
「首席架构师看Event Hub」Kafka的Spring 深入挖掘 -第1部分
「首席架构师看Event Hub」Kafka的Spring 深入挖掘 -第1部分
|
存储 JavaScript 小程序
Spring Event + DDD = 王炸!!上
Spring Event + DDD = 王炸!!上
|
设计模式 Java Spring
Spring Boot Event 观察者模式,轻松带你实现业务解耦!
Spring Boot Event 观察者模式,轻松带你实现业务解耦!
168 0
Spring Boot Event 观察者模式,轻松带你实现业务解耦!
|
设计模式 消息中间件 JavaScript
Spring Event 业务解耦神器,刷爆了
Spring Event 业务解耦神器,刷爆了
Spring Event 业务解耦神器,刷爆了