設計模式之發佈訂閱模式(5) Spring Events源碼解析


目錄結構java

一個'叫牀'的故事

以前講了深刻Spring Events事件驅動模型,發現一些小夥伴不知足於僅僅會用,還對事件驅動(Event Driven)的原理很感興趣,所以咱們這篇文章就帶你們看下Spring事件驅動的核心源碼。設計模式

對於事件驅動,你能夠跟生活中的實際場景聯繫一下,就很容易理解了。併發

好比你去賓館開房,次日早上6點要去趕飛機,就打電話給前臺,前臺記錄了你的房間號和叫醒時間,次日早上,前臺就在指定的時間挨個給須要叫醒的顧客打電話,叫他們起牀。異步

在這個故事裏,你就是一個監聽器,前臺就是一個廣播器,而早上6點提供叫醒服務就是一個事件。當這些早上六點被叫醒的監聽器們起牀之後,有的去了機場,有的去了火車站,這就是對同一個事件不一樣的監聽器進行了不一樣的邏輯處理。ide

事件監聽器源碼

你只要記住事件驅動中的三個角色,就很容易理解事件驅動的本質了,它們分別是:事件監聽器事件廣播器事件post

事件監聽器

咱們的事件監聽器都實現了ApplicationListener接口,這個接口中只有一個方法void onApplicationEvent(E event),用於處理監聽到的事件。至於監聽到事件之後怎麼辦,就是你的自由發揮餘地了。spa

事件廣播器

Spring經過事件廣播器ApplicationEventMulticaster接口將事件分配給專門的監聽器。線程

ApplicationEventMulticaster接口定義了3種方法:設計

  1. 添加監聽器:
void addApplicationListener(ApplicationListener<?> var1);

void addApplicationListenerBean(String var1);
複製代碼
  1. 刪除監聽器:
void removeApplicationListener(ApplicationListener<?> var1);

void removeApplicationListenerBean(String var1);

void removeAllListeners();
複製代碼
  1. 將事件發送到已註冊的監聽器:
void multicastEvent(ApplicationEvent var1);

void multicastEvent(ApplicationEvent var1, @Nullable ResolvableType var2);
複製代碼

AbstractApplicationEventMulticaster實現了基本的添加和刪除監聽器的方法。code

在實現類SimpleApplicationEventMulticaster的源碼裏,你能夠看到事件是被ApplicationEventMulticastermulticastEvent(ApplicationEvent event)方法發送到每一個已註冊的監聽器的。

@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
	ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
  //根據eventType獲取全部該類型事件已註冊的監聽器集合並遍歷
	for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
    //獲取線程池
		Executor executor = getTaskExecutor();
		if (executor != null) {
      //若是有線程池則併發觸發監聽器的方法
			executor.execute(() -> invokeListener(listener, event));
		}
		else {
      //沒有線程池則依次執行
			invokeListener(listener, event);
		}
	}
}
複製代碼

到這裏你應該明白SpringEvents事件驅動的原理了:

以Spring容器爲基礎,經過一個集合保存事件與事件監聽器之間的對應關係(想一想以前講的發佈者/訂閱者),而後當發佈事件的時候,根據事件類型獲取該事件全部的訂閱者,最後經過同步或異步的方式通知到每一個監聽器並執行監聽方法。

So easy !


相關連接

Wechat-westcall

相關文章
相關標籤/搜索