- Activiti權威指南
- 冀正
- 1366字
- 2020-11-28 16:00:05
6.3 注冊事件監聽器
下面詳細分析全局事件監聽器和具體類型的事件監聽器是如何注冊使用的。事件監聽器從應用范圍上可以劃分為兩種:一種是全局事件監聽器,負責監聽所有的事件;另一種是具體類型的事件監聽器,只負責部分事件的監聽,例如開發人員可以將所有流程引擎支持的事件按照業務使用場景進行劃分,可以定義一個類只負責監聽所有與任務有關的事件,也可以定義一個類只負責變量事件的監聽等,引擎設計具體類型的事件監聽器的主要意圖是方便開發人員細化、歸類事件,從而使事件監聽器的職責更加清晰和單一,代碼也更加容易維護。
上面提到事件監聽器的注冊和移除工作最終是通過ActivitiEventDispatcherImpl類中持有的ActivitiEventSupport實例對象來完成,下面詳細分析ActivitiEventSupport類是如何進行事件監聽器的注冊工作,整個處理流程如代碼清單6-2所示。
代碼清單6-2 ActivitiEventSupport.java

(1)第1行定義的addEventListener方法用于注冊全局事件監聽器。
addEventListener方法主要用于注冊全局事件監聽器,該方法的處理邏輯非常簡單,首先第2行對listenerToAdd參數進行非空校驗,如果該參數不為空,則第3行判斷eventListeners集合中是否已經存在了listenerToAdd,如果集合中不存在,則第4行將其添加到集合中,該操作主要是為了避免重復注冊事件監聽器。
(2)第7行定義的addEventListener方法用于注冊具體類型的事件監聽器。
首先第8行對listenerToAdd參數進行非空校驗,然后第9行判斷type參數是否為空,如果type參數為空則第10行直接將當前的事件監聽器作為全局事件監聽器進行處理,并通過第1行定義的方法將其注冊到eventListeners集合中;如果type參數不為空,則第12~13行循環遍歷type數組,并調用第17行定義的addTypedEventListener方法注冊具體類型的事件監聽器,該方法的處理邏輯如下。
? 第18行根據type參數從typedListeners集合中獲取該事件下所有的事件監聽器集合listeners。
? 第19行如果listeners集合為空,則首先初始化該集合并將其添加到typedListeners集合中。
? 第23行如果listeners集合中不存在listener元素,則將其添加到listeners集合中。
因為向eventListeners集合中添加元素時,可能存在多個線程同時對集合內容進行操作,所以需要考慮集合數據同步問題,因此上面三個方法中的方法簽名均使用了synchronized關鍵字進行修飾。
ActivitiEventSupport類中的eventListeners集合為List數據結構,初始化該集合時使用了Java中的CopyOnWriteArrayList類,該集合的初始化過程可以參考ActivitiEventSupport類的構造方法。這里需要對CopyOnWriteArrayList類詳細說明:CopyOnWriteArrayList類非常重要,可以使用在高并發場景中,基本思路是這樣的,例如存在一個集合,多個線程都要對集合內容進行操作,當任意一個線程想要改變集合內容時,首先需要把集合中的內容進行一次全復制并形成一個新的容器,這樣任何一個線程想要對原容器中的內容進行修改操作時,只會修改新生成容器中的內容,修改完畢之后將原容器的指針指向新容器,從而達到修改集合內容的目的,這是一種典型的懶惰延時策略,這樣做的好處就是每次修改容器內容時操作的永遠是新容器,從而可以對CopyOnWriteArrayList進行并發讀而不需要加同步鎖,由于當前容器集合永遠不會添加新元素,讀寫操作永遠在不同的容器中進行,是典型的讀寫分離思想。
CopyOnWriteArrayList類的缺點:在寫操作過程中內存會同時存在兩個容器,這樣程序就會占用大量的內存,并且寫操作過程客戶端可能需要從原容器中讀取最新的數據,而原容器的指針在指向新容器之前程序讀取的永遠是原容器的值,這樣可能會造成數據短時間內不一致,如果開發人員期望寫數據立刻就能被讀取到,必須要求保證數據的實時性、一致性,那么很顯然使用CopyOnWriteArrayList容器不是一種明智的選擇。
注意
Java中的Map為引用類型,如果獲取到某個Map的引用,則程序操作引用對象的時,本質上就是對Map進行操作。
- Python概率統計
- WildFly:New Features
- LabVIEW Graphical Programming Cookbook
- Hands-On Data Structures and Algorithms with JavaScript
- 基于Java技術的Web應用開發
- 人臉識別原理及算法:動態人臉識別系統研究
- 可解釋機器學習:模型、方法與實踐
- C#應用程序設計教程
- 劍指大數據:企業級數據倉庫項目實戰(在線教育版)
- iOS自動化測試實戰:基于Appium、Python與Pytest
- Cocos2d-x Game Development Blueprints
- 從程序員角度學習數據庫技術(藍橋杯軟件大賽培訓教材-Java方向)
- Vue.js光速入門及企業項目開發實戰
- STM8實戰
- Instant Pygame for Python Game Development How-to