一、前言
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 停止时发布。