觀察者模式是一種對象行為型設計模式,表示的是一種對象與對象之間具有的依賴關系。當一個對象發(fā)生改變的時候,這個對象所依賴的對象也會做出反應。
Spring 事件驅動模型就是觀察者模式中很經典的一個應用。Spring 事件驅動模型非常有用,在很多場景都可以起到解耦系統(tǒng)代碼的作用。比如,我們每次添加商品的時候,都需要重新更新商品索引,這個時候就可以利用觀察者模式來解決這個問題。
Spring 事件驅動模型中的三種角色
1. 事件角色
ApplicationEvent (org.springframework.context 包下) 充當事件的角色,這是一個抽象類,它繼承了 java.util.EventObject 并實現了 java.io.Serializable 接口。
Spring 中默認存在以下事件,他們都是對 ApplicationContextEvent 的實現(繼承自ApplicationContextEvent):
-
ContextStartedEvent:ApplicationContext啟動后觸發(fā)的事件; -
ContextStoppedEvent:ApplicationContext停止后觸發(fā)的事件; -
ContextRefreshedEvent:ApplicationContext初始化或刷新完成后觸發(fā)的事件; -
ContextClosedEvent:ApplicationContext關閉后觸發(fā)的事件。

2. 事件監(jiān)聽者角色
ApplicationListener 充當了事件監(jiān)聽者的角色,它是一個接口,里面只定義了一個 onApplicationEvent() 方法來處理 ApplicationEvent。ApplicationListener 接口類的源碼如下,所以在 Spring 中只要實現實現 onApplicationEvent() 方法即可完成監(jiān)聽事件:
package org.springframework.context;
import java.util.EventListener;
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E var1);
}
3. 事件發(fā)布者角色
ApplicationEventPublisher 充當了事件的發(fā)布者,它也是一個接口。
@FunctionalInterface
public interface ApplicationEventPublisher {
default void publishEvent(ApplicationEvent event) {
this.publishEvent((Object)event);
}
void publishEvent(Object var1);
}
ApplicationEventPublisher 接口的 publishEvent() 這個方法在 AbstractApplicationContext 類中被實現,閱讀這個方法的實現,可以發(fā)現實際上事件是通過 ApplicationEventMulticaster 來廣播出去的。
Spring 的事件流程總結
- 定義一個事件:實現一個繼承自
ApplicationEvent的類,并且寫相應的構造函數; - 定義一個事件監(jiān)聽者:實現
ApplicationListener接口,重寫onApplicationEvent()方法; - 使用事件發(fā)布者發(fā)布消息: 可以通過
ApplicationEventPublisher的publishEvent()方法發(fā)布消息。
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;
}
// 定義事件監(jiān)聽者,實現 ApplicationListener 接口,重寫 onApplicationEvent() 方法
@Component
public class DemoListener implements ApplicationListener<DemoEvent>{
//使用 onApplicationEvent 接收消息
@Override
public void onApplicationEvent(DemoEvent event) {
String msg = event.getMessage();
System.out.println("接收到的信息是:"+msg);
}
}
// 發(fā)布事件,通過 ApplicationEventPublisher 的 publishEvent() 方法發(fā)布消息
@Component
public class DemoPublisher {
@Autowired
ApplicationContext applicationContext;
public void publish(String message){
//發(fā)布事件
applicationContext.publishEvent(new DemoEvent(this, message));
}
}
當調用 DemoPublisher 的 publish() 方法,比如 demoPublisher.publish("hello"),控制臺就會打印出:接收到的信息是:hello 。