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 停止时发布。
相关推荐
winks35 分钟前
Spring Task的使用
java·后端·spring
Null箘6 分钟前
从零创建一个 Django 项目
后端·python·django
秋意钟15 分钟前
Spring新版本
java·后端·spring
椰椰椰耶17 分钟前
【文档搜索引擎】缓冲区优化和索引模块小结
java·spring·搜索引擎
小蜗牛慢慢爬行35 分钟前
有关异步场景的 10 大 Spring Boot 面试问题
java·开发语言·网络·spring boot·后端·spring·面试
A小白59081 小时前
Docker部署实践:构建可扩展的AI图像/视频分析平台 (脱敏版)
后端
goTsHgo1 小时前
在 Spring Boot 的 MVC 框架中 路径匹配的实现 详解
spring boot·后端·mvc
钱多多_qdd1 小时前
spring cache源码解析(四)——从@EnableCaching开始来阅读源码
java·spring boot·spring
waicsdn_haha1 小时前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
Q_19284999061 小时前
基于Spring Boot的摄影器材租赁回收系统
java·spring boot·后端