多執行個體實作會或簽,依次審批
如果你去找 Activiti 的會或簽解決方案,肯定會發現 Activiti 的多執行個體功能。
多執行個體就是一個節點在運作時産生多個執行個體,這些節點的配置大體上都是相似的,隻有參數上可能有所不同,這些執行個體可以配置成串行執行或者并行執行。比如 UserTask 産生多個執行個體,每個執行個體隻有負責人不同,會或簽就是用這個實作的。
最簡單的一個會簽配置如下:
<!--會簽配置-->
<userTask id="someTask" name="Activiti is awesome!" activiti:assignee="${user}">
<multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${userList}"
activiti:elementVariable="user"/>
</userTask>
上面的配置用僞代碼表示如下:
# userList 是清單類型的流程變量
for user in userList:
用 user 作為任務負責人(assignee)執行 UserTask
預設情況下隻有當所有的執行個體都完成時,這個 UserTask 才會完成。是以上面這個配置其實就是會簽,所有負責人同時進行任務,等到所有任務都完成時,才能結束這個 UserTask。
需要注意的是,因為
isSequential="false"
,是以這些執行個體都是并行執行的,也就是這些執行個體都是同時産生的。如果設定為 true,這些執行個體則會“依次”執行,也就是第一個負責人完成任務後,第二個執行個體才會産生,這樣依次下去,是以隻要将
isSequential
設定為
true
就可以實作依次審批了:
<!--依次審批配置-->
<userTask id="someTask" name="Activiti is awesome!" activiti:assignee="${user}">
<multiInstanceLoopCharacteristics isSequential="true" activiti:collection="${userList}"
activiti:elementVariable="user"/>
</userTask>
“或簽”又該如何實作呢?
multiInstanceLoopCharacteristics
還支援配置結束條件,通過結束條件的配置即可實作或簽:
<!--或簽配置-->
<userTask id="someTask" name="Activiti is awesome!" activiti:assignee="${user}">
<multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${userList}"
activiti:elementVariable="user">
<completionCondition>${nrOfCompletedInstances == 1}</completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>
completionCondition
裡面填寫的就是結束條件,其中
nrOfCompletedInstances
是多執行個體節點的内置變量,表示已經完成執行個體數目,除此之外還有下面幾個内置變量:
-
: 執行個體總數nrOfInstances
-
: 已完成執行個體總數nrOfCompletedInstances
-
:目前活躍執行個體總數nrOfActiveInstances
通過這幾個變量可以配置出更加豐富的結束條件,比如我可以配置一個 "半會簽",即隻要一半的人通過就行了:
<!--半會簽配置-->
<userTask id="someTask" name="Activiti is awesome!" activiti:assignee="${user}">
<multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${userList}"
activiti:elementVariable="user">
<completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.5}</completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>
除了 UserTask 可以多執行個體,Activiti 上還有好多節點支援多執行個體,配置也都是相似的:
- User Task
- Script Task
- Java Service Task
- Web Service Task
- Business Rule Task
- Email Task
- Manual Task
- Receive Task
- (Embedded) Sub-Process
- Call Activity
另外,多執行個體的這個概念與配置方法都是寫在 BPMN 2.0 規範中的,而不是 Acitiviti 獨有的,他們在 BPMN 的圖形如下(在節點上有三條豎線表示并行,有三條橫線表示串行):

是以使用這種配置方式,以後想切引擎也是非常友善的。
原理
多執行個體在代碼上采用的是裝飾器模式,使用
MultiInstanceActivityBehavior
裡面包一個功能節點的
ActivityBehavior
,比如
UserTaskActivityBehavior
。
MultiInstanceActivityBehavior
的兩個子類,
ParallelMultiInstanceBehavior
和
SequentialMultiInstanceBehavior
就分别代表并行多執行個體和串行多執行個體的邏輯。
并行的情況會給每一個執行個體生成一個 execution,當滿足
completionCondition
時,恢複父 execution 的執行,并且删除它的所有子 execution(就是節點産生的多執行個體):
至于串行多執行個體,這整個一串執行個體共用一個子 execution:
如果原理部分看得比較蒙圈,建議先去看一下我的
上一篇文章,然後再來看這裡的原理就一目了然了。
參考
- Activiti User Guide-Multi-instance
- Activiti多執行個體會簽功能