首頁>技術>

本文activiti原始碼版本為7.1.0.M5。

activiti遵循了DDD(領域驅動設計),採用CQRS的架構。

1.實體

首先說下實體、值物件的命名規則,可以參考COLA命名規範:

activiti類似,以Entity結尾的表示領域模型中的實體,但是activiti更加複雜一點,首先定義了一個Entity介面,每個具體的實體介面繼承了這個介面,例如TaskEntity介面,每個實體介面又有一個實體實現類,例如TaskEntityImpl,其中包含了TaskEntityImpl這個實體的基本屬性和基本操作,這裡的基本操作指的應該是領域模型的動作,具體到Task上來說就是操作變數資訊,操作候選人資訊等。因此更準確的說領域模型的實體應該是以EntityImpl結尾。

2. CQRS

CQRS是領域驅動設計中的一種架構模式,即命令查詢的責任分離Command Query Responsibility Segregation 。具體來說就是將CRUD操作分離,CUD操作透過Command實現,R即查詢直接操作資料庫。當一個Command進來時,從資源庫Repository載入一個聚合aggregate物件群,然後執行其方法和行為。查詢和命令分離的模式為系統性能最佳化提供了更大的空間,例如很容易就想到讀寫分離,查詢服務直接查詢從庫,Command操作主庫。主庫和從庫之間透過領域事件保證資料同步。activiti提供了事件機制,可以自己訂閱感興趣的事件。稍後專門說事件機制。這種架構的好處在於實現透明的分散式處理,當一個Command進來時,從資源庫Repository載入一個聚合aggregate物件群,然後執行其方法和行為,然後觸發一個事件,事件監聽者收到事件後做相應的處理。這給了我們很大的操作空間,例如我們也可以查詢服務採用快取,當監聽到事件時,更新快取資料。

我們猜想activiti正常的CQRS應該如下:

其中Query的各種實現介面應該直接查詢資料庫或者快取,Command操作資料庫併發布領域事件。但是看Query實現發現並不是這樣,建立Query實現後,透過list(),count()等方法查詢資料,這些方法的實現在AbstractQuery類中,以list()為例,原始碼乳如下:

發現Query的各種實現也是採用了命令模式,說明Query的各種實現也實現了Command介面,以TaskQueryImpl為例,其類圖如下圖所示:

因此activiti的CQRS應該如下:

每一個Command都是交給commandExecutor的execute()方法去執行的,實際上執行的是Command中的execute()方法。在activiti中每個Command是一個事務,Command內的操作可以保證資料一致性。

通常一個Command中主要做下面事情:

校驗協調領域模型或者領域服務持久化釋出領域事件3.領域事件

activiti定義了一套事件通知機制,當有關流程的重要事件發生時會發送相應的領域事件,所有的事件都定義在一個列舉類ActivitiEventType中,例如流程啟動,流程完成,任務生成,任務完成等。以任務完成為例,簡單介紹下事件通知機制:

完成任務使用的Command是CompleteTaskCmd,在CompleteTaskCmd中的execute()方法中可以看到實際執行完成任務操作的是AbstractCompleteTaskCmd類中的executeTaskComplete方法,在這個方法中我們暫時忽略其他實現,重點關注領域事件通知機制。程式碼如下:

透過事件分發器ActivitiEventDispatcher分發對應的事件,這裡對應的是ActivitiEventType.TASK_COMPLETED即任務完成事件。

分發事件後,可以根據需要訂閱事件,實現ActivitiEventListener介面並透過processEngineConfiguration.setEventListeners方法將自己定義的Listenter新增到ActivitiEventDispatcher中,然後自定義的listener就會收到activiti釋出的事件。

activiti遵循了領域驅動設計的思想,後續我會繼續分析activiti原始碼。

8
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Java多執行緒--關鍵字ThreadLocal