Spring中的事件驱动模型

一、前言

Spring时间事件监听也叫Spring事件驱动。是观察者模式(观察者模式也叫发布订阅模式)的一种实现,只要是观察者模式,就含有主题,发布者和订阅者。

基于事件监听,可以实现代码的解耦。方便拓展业务功能

二、观察者模式

1、观察者模式简介

当对象间存在一对多的关系时,则使用观察者模式。比如,当一个对象被修改时,则会自动通知它的依赖对象。

和rabbitMQ、RocketMQ、Kafka消息队列有点像

2、观察者模式角色

  • Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
  • ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  • Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
  • ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

三、Spring事件驱动模型

1、Spring事件驱动模型角色

(一)事件(Event)

在 Spring 事件驱动模型中,事件是一个数据对象,它代表了在应用程序中发生的某个事情。例如,在一个电商系统中,可能会有 "订单创建事件"、"用户注册事件" 等。事件类通常是一个简单的 Java 对象(POJO),它可以包含与事件相关的属性。例如,一个订单创建事件可能包含订单的编号、下单用户的信息、订单的金额等属性。

如果我们需要实现时间传播的话,我们首先需要定义自己的事件类去实现ApplicationEvent接口

(二)事件发布者(Publisher)

事件发布者是负责产生和发布事件的组件。在 Spring 中,任何一个 Spring 管理的 Bean 都可以成为事件发布者。当某个业务逻辑执行到特定的阶段,满足了某个事件发生的条件时,事件发布者就会创建一个相应的事件对象,并将其发布到 Spring 的应用上下文中。例如,在订单服务中,当成功创建一个订单后,订单服务就可以作为事件发布者发布 "订单创建事件"。

需要有一个对象去发布该事件。ApplicationContext是一个天然的事件发布源,通常可以使用ApplicationEventPublisherAware接口注入上下文中的ApplicationEventPublisher,可以通过它来发布事件

(三)事件监听器(Listener)

事件监听器是用于接收和处理事件的组件。监听器会订阅它感兴趣的事件类型,当事件发布者发布了该类型的事件时,监听器就会被触发并执行相应的逻辑。例如,对于 "订单创建事件",可能会有一个监听器负责发送订单创建的通知邮件给用户,另一个监听器负责更新库存系统以扣除订单中的商品数量。

定义自己的事件监听器,实现ApplicationListener接口

2、代码案例

1、定义一个事件类

java 复制代码
public class OrderCreateEvent extends ApplicationEvent{
   private final Order order;
   
   public OrderCreateEvent(Object source,Order order){
     super(source);
     this.order = order;
   }
   
   public Order getOrder(){
     return order;
    }
}

2、定义一个事件监听器

java 复制代码
@Compoent
public class OrderCreateEventListener implements ApplicationListener<OrderCreateEvent> {

    @Override
    public void onApplicationEvent(OrderCreateEvent event){
           //TODO 监听到订单创建事件后,需要处理的业务
           System.out.println("监听到订单创建事件后,需要处理的业务");
    }
}

除了实现ApplicationListner接口之外,我们也可以使用注解的方式

java 复制代码
@Compoent
public class OrderCreateEventListener  {

    @EventListener
    public void handleOrderCreateEvent(OrderCreateEvent event){
           //TODO 监听到订单创建事件后,需要处理的业务
           System.out.println("监听到订单创建事件后,需要处理的业务");
    }
}

3、在业务代码中发布事件

java 复制代码
@Service
public class OrderService implemenst ApplicationEventPublisherAware{

    private ApplicationEventPublisher allicationEventPublisher;
    
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher){
    
    this.applicationEventPublisher = applicationEventPublisher;
    }
    
    public void createOrder(){
      Order order = new Order();
      order.setNo("1");
      order.setName("手机");
      //TODO 操作数据库,保存订单
      System.out.println("操作数据库,保存订单");
      
      //发布事件
      applicationEventPublisher.pushEvent(new OrderCreateEvent(this,order));
      
      
    }
    

}

4、异步事件的处理

默认我们的事件处理是同步的,如果希望事件处理是异步的,则需要开启异步支持

首先是在配置类上开启异步支持

java 复制代码
@Configuration
@EnableAsync
public class AsyncConfig{

}

然后在监听方法上使用 @Async 注解

java 复制代码
@Compoent
public class OrderCreateEventListener  {

    @Async
    @EventListener
    public void handleOrderCreateEvent(OrderCreateEvent event){
           //TODO 监听到订单创建事件后,需要处理的业务
           System.out.println("监听到订单创建事件后,需要处理的业务");
    }
}

3、Spring内置事件

上述的代码案例,指的是我们自定义事件。Spring提供了很多的内置事件。可以帮助我们在Spring容器启动或者关闭的时候处理某些业务操作

  • ContextRefreshedEvent:当 ApplicationContext 被初始化或刷新时发布。
  • ContextClosedEvent:当 ApplicationContext 关闭时发布。
  • ContextStartedEvent:当 ApplicationContext 启动时发布。
  • ContextStoppedEvent:当 ApplicationContext 停止时发布。
相关推荐
lastHertz9 分钟前
Golang 项目中使用 Swagger
开发语言·后端·golang
渣哥10 分钟前
面试高频:Spring 事务传播行为的核心价值是什么?
javascript·后端·面试
调试人生的显微镜15 分钟前
iOS 代上架实战指南,从账号管理到使用 开心上架 上传IPA的完整流程
后端
本就一无所有 何惧重新开始19 分钟前
Redis技术应用
java·数据库·spring boot·redis·后端·缓存
低音钢琴32 分钟前
【SpringBoot从初学者到专家的成长11】Spring Boot中的application.properties与application.yml详解
java·spring boot·后端
越千年40 分钟前
用Go实现类似WinGet风格彩色进度条
后端
淳朴小学生1 小时前
静态代理和动态代理
后端
渣哥1 小时前
数据一致性全靠它!Spring 事务传播行为没搞懂=大坑
javascript·后端·面试
三七互娱后端团队1 小时前
Serena语义检索在AI CodeReview中的应用
后端