天天看點

Activiti原理分析(二)多執行個體,會或簽與依次審批

多執行個體實作會或簽,依次審批

如果你去找 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 上還有好多節點支援多執行個體,配置也都是相似的:

另外,多執行個體的這個概念與配置方法都是寫在 BPMN 2.0 規範中的,而不是 Acitiviti 獨有的,他們在 BPMN 的圖形如下(在節點上有三條豎線表示并行,有三條橫線表示串行):

Activiti原理分析(二)多執行個體,會或簽與依次審批

是以使用這種配置方式,以後想切引擎也是非常友善的。

原理

多執行個體在代碼上采用的是裝飾器模式,使用

MultiInstanceActivityBehavior

裡面包一個功能節點的

ActivityBehavior

,比如

UserTaskActivityBehavior

MultiInstanceActivityBehavior

的兩個子類,

ParallelMultiInstanceBehavior

SequentialMultiInstanceBehavior

就分别代表并行多執行個體和串行多執行個體的邏輯。

Activiti原理分析(二)多執行個體,會或簽與依次審批

并行的情況會給每一個執行個體生成一個 execution,當滿足

completionCondition

時,恢複父 execution 的執行,并且删除它的所有子 execution(就是節點産生的多執行個體):

Activiti原理分析(二)多執行個體,會或簽與依次審批

至于串行多執行個體,這整個一串執行個體共用一個子 execution:

Activiti原理分析(二)多執行個體,會或簽與依次審批

如果原理部分看得比較蒙圈,建議先去看一下我的

上一篇文章

,然後再來看這裡的原理就一目了然了。

參考

繼續閱讀