深入理解Spring事件监听机制
在之前的文章中,我分享过一篇关于观察者模式的文章,如有有兴趣的可以去看一下,对理解Spring事件监听机制有些帮助。
言归正传,下面我们进行Spring事件监听机制的分享
1: Spring事件监听
Spring 的事件监听机制是在 JDK 事件监听的基础上进行的扩展,也是在典型观察者模式上的进一步抽象和改进。Spring 中提供了一套默认的事件监听机制,在容器初始化时便使用了这套机制。并且 Spring 也提供了事件监听机制的接口扩展能力,开发者基于此可快速实现自定义的事件监听功能
2: Spring事件监听的核心原理
Spring 的监听机制是非常优秀的思想,它能够很好地实现代码解耦,将业务逻辑与非业务逻辑分离,让程序变得更加灵活和可维护。
首先我们要理解几个概念
事件源: 事件的触发者,也即是事件发布者
事件: 描述发生了什么事情的对象,也就是我们事件的信息
事件监听器: 监听到事件的发生的时候,做一些处理
实现Spring事件机制主要有4个接口:
1: 事件源 ApplicationEventPublisher
作用: 用于发布事件
@FunctionalInterface
public interface ApplicationEventPublisher {
default void publishEvent(ApplicationEvent event) {
publishEvent((Object) event);
}
//发布事件
void publishEvent(Object event);
}
2: 事件监听器 ApplicationListener
作用: 监听对应的事件,做逻辑处理
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
//监听事件
void onApplicationEvent(E event);
static <T> ApplicationListener<PayloadApplicationEvent<T>> forPayload(Consumer<T> consumer) {
return event -> consumer.accept(event.getPayload());
}
}
3: 事件 ApplicationEvent
作用: 构造事件模型
public abstract class ApplicationEvent extends EventObject {
/** use serialVersionUID from Spring 1.2 for interoperability. */
private static final long serialVersionUID = 7099057708183571937L;
/** System time when the event happened. */
private final long timestamp;
//构造事件对象,带时间
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
//构造事件对象,定制时间区
public ApplicationEvent(Object source, Clock clock) {
super(source);
this.timestamp = clock.millis();
}
//当前事件的时间
public final long getTimestamp() {
return this.timestamp;
}
}
4: 事件监听器管理 ApplicationEventMulticaster
作用: 负责事件的发布和监听
public interface ApplicationEventMulticaster {
//用于向事件广播器注册一个监听器。在广播器发送事件时,这个监听器将会接收到事件。
void addApplicationListener(ApplicationListener<?> listener);
//用于将一个已经注册的监听器从事件广播器中移除。
void removeApplicationListener(ApplicationListener<?> listener);
//用于移除所有注册的监听器。
void removeAllListeners();
//用于向所有已注册的监听器广播一个事件。
void multicastEvent(ApplicationEvent event);
}
3: 代码示例
了解上面的原理,我们看下在应用中是怎么使用的。
1: 创建监听类,将类注入到Spring容器中
@Component
public class OrderEventListener {
//这里使用了@Async注解异步线程执行,起作用的前提是开启@EnableAsync注解
@EventListener
@Async
public void handleOrderEvent(OrderEvent event) {
Order order = event.getOrder();
String message = "您有一个新的订单,订单号为:" + order.getOrderId();
System.out.println("message = " + message);
}
}
2: 创建事件模型,用于事件信息传输
public class OrderEvent extends ApplicationEvent {
public OrderEvent(Object source) {
super(source);
}
private Order order;
public OrderEvent(Object source