观察者模式是一种对象行为型设计模式,表示的是一种对象与对象之间具有的依赖关系。当一个对象发生改变的时候,这个对象所依赖的对象也会做出反应。
Spring 事件驱动模型就是观察者模式中很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以起到解耦系统代码的作用。比如,我们每次添加商品的时候,都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。
Spring 事件驱动模型中的三种角色
1. 事件角色
ApplicationEvent
(org.springframework.context
包下) 充当事件的角色,这是一个抽象类,它继承了 java.util.EventObject
并实现了 java.io.Serializable
接口。
Spring 中默认存在以下事件,他们都是对 ApplicationContextEvent
的实现(继承自ApplicationContextEvent
):
-
ContextStartedEvent
:ApplicationContext
启动后触发的事件; -
ContextStoppedEvent
:ApplicationContext
停止后触发的事件; -
ContextRefreshedEvent
:ApplicationContext
初始化或刷新完成后触发的事件; -
ContextClosedEvent
:ApplicationContext
关闭后触发的事件。
ApplicationEvent-Subclass
2. 事件监听者角色
ApplicationListener
充当了事件监听者的角色,它是一个接口,里面只定义了一个 onApplicationEvent()
方法来处理 ApplicationEvent
。ApplicationListener
接口类的源码如下,所以在 Spring 中只要实现实现 onApplicationEvent()
方法即可完成监听事件:
package org.springframework.context;
import java.util.EventListener;
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E var1);
}
3. 事件发布者角色
ApplicationEventPublisher
充当了事件的发布者,它也是一个接口。
@FunctionalInterface
public interface ApplicationEventPublisher {
default void publishEvent(ApplicationEvent event) {
this.publishEvent((Object)event);
}
void publishEvent(Object var1);
}
ApplicationEventPublisher
接口的 publishEvent()
这个方法在 AbstractApplicationContext
类中被实现,阅读这个方法的实现,可以发现实际上事件是通过 ApplicationEventMulticaster
来广播出去的。
Spring 的事件流程总结
- 定义一个事件:实现一个继承自
ApplicationEvent
的类,并且写相应的构造函数; - 定义一个事件监听者:实现
ApplicationListener
接口,重写onApplicationEvent()
方法; - 使用事件发布者发布消息: 可以通过
ApplicationEventPublisher
的publishEvent()
方法发布消息。
Example:
// 定义事件,继承自 ApplicationEvent 并且重写相应的构造函数
public class DemoEvent extends ApplicationEvent{
private static final long serialVersionUID = 1L;
private String message;
public DemoEvent(Object source,String message){
super(source);
this.message = message;
}
public String getMessage() {
return message;
}
// 定义事件监听者,实现 ApplicationListener 接口,重写 onApplicationEvent() 方法
@Component
public class DemoListener implements ApplicationListener<DemoEvent>{
//使用 onApplicationEvent 接收消息
@Override
public void onApplicationEvent(DemoEvent event) {
String msg = event.getMessage();
System.out.println("接收到的信息是:"+msg);
}
}
// 发布事件,通过 ApplicationEventPublisher 的 publishEvent() 方法发布消息
@Component
public class DemoPublisher {
@Autowired
ApplicationContext applicationContext;
public void publish(String message){
//发布事件
applicationContext.publishEvent(new DemoEvent(this, message));
}
}
当调用 DemoPublisher
的 publish()
方法,比如 demoPublisher.publish("hello")
,控制台就会打印出:接收到的信息是:hello
。