幾句話熟悉Laravel/Symfony 事件系統

咱們知道,laravel/symfony 框架是由一堆堆 components 組件粘合在一塊兒的。其中會有一個 event component 組件,比較特殊,它像一箇中介,是框架層全局 component,專門負責不一樣component間相互通訊傳數據的。html

說它是全局的,意思是,整個請求生命週期內,event 對象是單例的,對象不能新建實例,每次從容器中獲取標識爲 'event' 的 event 對象仍是最開始的 event 對象,爲啥要這樣搞?很簡單啊,若是不是單例的,那第一個 event component 裏註冊了 10 個事件 event,在某個 component 裏想要觸發 event 對象裏的一個發郵件事件 'mail',但若是此時從容器中拿到的 event component 不是原來的 event component,那就找不到那個 mail 事件對應的處理器 handler 了。能夠看看 laravel 的 EventServiceProvider 在往容器中註冊 'event' 對象時是使用的 singleton() 單例註冊的,這樣保證 event 對象永遠是那一個。laravel

說它負責跨組件通訊,意思是好比對於 database 下的一個 model 對象如 account model,當邏輯處理到 save 完一個 account model 到數據庫時,若是須要再增長几個邏輯,如發個郵件 mail,數據入數據庫前須要驗證 validation,給這個 account 寫個日誌 log 等等,這幾個邏輯須要 Mail Component/Validation Component/Log Component 裏面的對象去處理,難道我要在 $account->save() 的後面在寫一大坨這些邏輯?那代碼豈不亂七八糟。況且我想在 save 前和 save 後再搞一些邏輯,那不完蛋了。有沒有這樣一種實踐方式讓我 save 前一兩行代碼,save 後一兩行代碼,把這些邏輯解耦爲各個小邏輯呢,這樣代碼豈不更清爽。數據庫

(1) 爲啥須要事件系統?

代碼層面,爲了代碼解耦,把在一處的一大坨邏輯解耦成多處細分代碼;性能考慮,事件的隊列功能模擬了異步處理,把耗時的任務放在隊列裏,讓隊列一個個去慢慢處理這些任務。數組

(2) 事件架構是如何構成的?

事件架構其實很簡單,它是一個框架層的全局 component: event component,經過上面的描述知道它應該具有幾個功能: 事件註冊功能事件觸發功能,再加一個高級功能把事件放在隊列裏異步處理,如 laravel 裏事件註冊功能\\Illuminate\\Events\\Dispatcher::listen(),事件觸發功能\\Illuminate\\Events\\Dispatcher::dispatch()架構

一個事件系統就這麼簡單。框架

(3) 一個事件 event 能夠有多個處理器 handler/listener,一個 handler/listener 能夠監聽多個事件,這個應該如何讓 event component 支持呢?

要求多個 handler/listener (一個 callable 或是一個 class name)監聽一個事件 'event',很簡單,那就屢次註冊\\Illuminate\\Events\\Dispatcher::listen($event_name, $handler),$event_name 同樣,$handler 不同而已,會按照註冊順序執行 $handler,固然 symfony 支持在第三個參數就是 priority,設置 $handler 執行順序。
要求一個 handler/listener 能夠監聽多個 event,很簡單,把 handler 作成一個類 class,而後裏面作個 $events 數組屬性設置要監聽哪些 events 就行,laravel/symfony 都叫這個 handler 爲 Event Subscribers,僅此而已。異步

不想去畫圖來詳細說明了,根據上面幾句話,再去從架構層面去看 laravel event / symfony event 的事件系統文章,就很簡單了,建議仔細閱讀下官網這兩篇文章。其餘細節都是爲了上面這些設計目的服務的。ide

說了這麼多,一句話歸納:事件系統就像是框架層的全局數據庫,具備存儲、註冊和觸發事件功能,解耦代碼,實現跨組件通訊。。性能

相關文章
相關標籤/搜索