[Java Framework] [Spring] Spring Event / 事件的使用 二: Transactional Event

简介: [Java Framework] [Spring] Spring Event / 事件的使用 二: Transactional Event

简介

Spring Event 主要是为了解耦代码使用, 但是会有这样一种情况, 订单创建成功打印小票和添加库存,如果订单创建失败了,事件已经发送成功了,像这种情况肯定不能容忍的,所以给事件添加上事务

🧲[官方文档] Additional Capabilities of the ApplicationContext

🧲[相关文章] Spring Event / 事件的使用 一: ApplicationEvent

方法 / 步骤

  • 添加依赖
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>

一: 定义事件实体

  • 📄 Order.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
    private Long orderId;
    private String name;
}
  • 📄OrderPayEvent.java
/**
 * Description:
 *
 * @author: YangGC
 */
public class OrderPayEvent extends ApplicationEvent {

    /**
     * 当前订单对象
     * @param source
     */
    private Order order;

    public OrderPayEvent(Object source) {
        super(source);
        this.order = (Order) source;
    }

    public Order getOrder() {
        return order;
    }
}

二: 定义监听器

定义监听者的方式,Spring提供了两种,一种是接口方式,一种是注解方式。

2.1: 接口方式

这里定义了两个监听者,实现泛型接口ApplicationListener类型为我们刚定义的OrderPayedEvent这里加上Order注解,是因为我们有多个监听者,有此业务场景中可能会有顺序的要求!
  • 📄OrderPayedPrinterListener.java
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;

/**
 * Description:
 *
 * @author: YangGC
 */
@Component
public class OrderPayedListener {

    @TransactionalEventListener(fallbackExecution = true)
    public void handler(OrderPayEvent orderPayEvent){
        //todo 添加业务处理
        System.out.println(orderPayEvent.toString());
        System.out.printf("【线程 - %s 】订单成功成功:第一步,打印小票%n", Thread.currentThread().getName());
        System.out.printf("【线程 - %s 】订单成功成功:第二步,发送通知商品中心添加库存%n", Thread.currentThread().getName());
    }
}

三: 发送事件

  • 📄 ShoppingMallConsumerApplication.java
@SpringBootApplication
public class ShoppingMallConsumerApplication implements CommandLineRunner {
    public static void main(String[] args) {
        SpringApplication.run(ShoppingMallConsumerApplication.class);
    }

    //这里注入 应用上下文,可以注入 applicationEventPublisher
    @Resource
    ApplicationContext context;
//    @Resource
//    ApplicationEventPublisher applicationEventPublisher;
    @Override
    public void run(String... args) throws Exception {
        context.publishEvent(new OrderPayEvent(new Order(100L,"酸菜鱼")));
    }
}
  • 打印结果
com.iooiee.event.OrderPayEvent[source=Order(orderId=100, orderName=酸菜鱼)]
【线程 - main 】订单成功成功:第一步,打印小票
【线程 - main 】订单成功成功:第二步,发送通知商品中心添加库存

异步处理

ApplicationEvent对异步支持是怎么样的呢?

只要在启动类上加上@EnableAsync,在监听器类注解加上@Async

  • 📄 ShoppingMallConsumerApplication.java
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionalEventListener;

/**
 * Description:
 *
 * @author: YangGC
 */
@Component
public class OrderPayedListener {

    @Async
    @TransactionalEventListener(fallbackExecution = true)
    public void handler(OrderPayEvent orderPayEvent){
        //todo 添加业务处理
        System.out.println(orderPayEvent.toString());
        System.out.printf("【线程 - %s 】订单成功成功:第一步,打印小票%n", Thread.currentThread().getName());
        System.out.printf("【线程 - %s 】订单成功成功:第二步,发送通知商品中心添加库存%n", Thread.currentThread().getName());
    }
}
  • 打印结果
com.iooiee.event.OrderPayEvent[source=Order(orderId=100, orderName=酸菜鱼)]
【线程 - task-1 】订单成功成功:第一步,打印小票
【线程 - task-1 】订单成功成功:第二步,发送通知商品中心添加库存

事务处理

记得在事务处理中,异步操作在事务提交之后进行事件发送,不然可能查询不到同事务里面处理的数据

TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
    @Override
    public void afterCommit(){
        context.publishEvent(new OrderPayEvent(new Order(100L,"酸菜鱼")));
    }
});

参考资料 & 致谢

[1] Spring事件,ApplicationEvent在业务中的应用

目录
相关文章
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
98 2
|
5天前
|
Java Spring
Java Spring Boot监听事件和处理事件
通过上述步骤,我们可以在Java Spring Boot应用中实现事件的发布和监听。事件驱动模型可以帮助我们实现组件间的松耦合,提升系统的可维护性和可扩展性。无论是处理业务逻辑还是系统事件,Spring Boot的事件机制都提供了强大的支持和灵活性。希望本文能为您的开发工作提供实用的指导和帮助。
43 15
|
1天前
|
Java 开发者 Spring
java springboot监听事件和处理事件
通过上述步骤,开发者可以在Spring Boot项目中轻松实现事件的发布和监听。事件机制不仅解耦了业务逻辑,还提高了系统的可维护性和扩展性。掌握这一技术,可以显著提升开发效率和代码质量。
18 6
|
3天前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
7天前
|
Java 开发者 Spring
Java Springboot监听事件和处理事件
通过这些内容的详细介绍和实例解析,希望能帮助您深入理解Spring Boot中的事件机制,并在实际开发中灵活应用,提高系统的可维护性和扩展性。
33 7
|
1月前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
67 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
22天前
|
设计模式 Java Spring
Spring Event 的幕后
Spring Event 基于观察者模式,实现模块间松散耦合的通信。通过事件(Event)、事件发布者(Publisher)和事件监听器(Listener)三个核心组件,Spring Event 可以轻松实现业务解耦。Spring 容器在启动时会初始化 `ApplicationEventMulticaster`,扫描并注册所有事件监听器,通过调用 `multicastEvent()` 方法将事件广播给所有注册的监听器。
|
2月前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
259 12
基于开源框架Spring AI Alibaba快速构建Java应用
|
2月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
2月前
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。
59 0