天天看點

Flowable 6.4 多執行個體會簽 審批人設定、結果判斷、會簽後走向

參考文章:​​http://huan1993.iteye.com/blog/2249764​​ 第一部分是部署檔案的大緻說明,其他文章也有介紹,熟悉的可以跳過

首先部署檔案中:

<userTask id="_7" name="評估" flowable:assignee="${per}">
      <extensionElements>
        <flowable:taskListener event="complete" class="com.taikang.sorceress.modules.workflow.listener.IdeaTaskListener"></flowable:taskListener>
        <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
      <multiInstanceLoopCharacteristics isSequential="false" flowable:collection="pers" flowable:elementVariable="per">
        <completionCondition>${multiInstance.accessCondition(execution)}</completionCondition>
      </multiInstanceLoopCharacteristics>
</userTask>
      

userTask标簽中 ,flowable:assignee 表示取得multiInstanceLoopCharacteristics标簽中flowable:elementVariable的值,而flowable:elementVariable的值表示flowable:collection這個審批人集合變量的每一個審批人變量;

extensionElements标簽中,設定的是綁定的TaskListener;

multiInstanceLoopCharacteristics 标簽中,設定的是多執行個體特點,其中:

isSequential屬性表示是否串行,串行也就是說是否按順序挨個兒執行。

flowable:collection是在上一個任務節點中放在map裡的key值。

ExecutionListener和TaskListener以及多執行個體任務結束條件類

下面說一下多執行個體任務的配置設定人環節以及結束條件部分。

配置設定人可以像其他文章一樣使用ServiceTask讀取上個節點存儲的審批人。我是覺得必要性不大,直接在上個任務節點把審批人的集合存到map裡完成任務即可。

map.put(“pers”, Arrays.asList(pers_arr));

taskService.complete(taskId, map);

類似于這樣。注意map的key和部署檔案中flowable:collection的值相同即可。

然後說一下多執行個體任務結束條件判定部分的坑。我當時看其他文章一直不明白為什麼有了結束條件類還要綁TaskListener類,同樣都可以用作監聽完成任務之後的回調。

關鍵就在于ExecutionListener與TaskListener的可複寫方法notify。這個方法的參數是DelegateExecution與DelegateTask。這兩個類官方API的解釋是 used in JavaDelegates and ExecutionListeners以及used in JavaDelegates and DelegateListeners。而JavaDelegates是用ServiceTask配置設定審批人的方式,是直接在DelegateExecution的變量調用setVariable方法設定審批人的。

這兩種設定審批人的方法其實都是設定在了多執行個體任務所處的execution裡的,是以均可。

差別在于多執行個體任務每次每個審批人comlete了之後。

首先說一下調用順序,當taskService.complete(taskId, map)調用完之後,如果TaskListener的監聽事件設定為comlete,那麼這裡會先觸發TaskListener中的notify方法,之後再觸發結束條件類的自定義結束函數。并且多執行個體任務中每次complete了之後都會順序觸發這兩個類中的回調函數。

這是我的結束條件判斷類:

public class MultiInstanceCompleteTask implements Serializable {
    /**
     * 評估結果判定條件
     * @param execution 配置設定執行執行個體
     */
    public boolean accessCondition(DelegateExecution execution){
        //已完成的執行個體數
        int completedInstance = (int)execution.getVariable("nrOfCompletedInstances");
        //否決判斷,一票否決
        if (execution.getVariable(“reject”) != null){
            int rejectCount = (int)execution.getVariable(“reject”);
            if(rejectCount > 0 ){
                //輸出方向為拒絕
                execution.setVariable("outcome", “reject”);
                //一票否決其他執行個體沒必要做,結束
                return true;
            }
        }
        //所有執行個體任務未全部做完則繼續其他執行個體任務
        if(completedInstance != sum){
            return false;
        }else{
            //輸出方向為贊同
            execution.setVariable("outcome",“approved”);
            //所有都做完了沒被否決,結束
            return true;
        }
    }
      

我部署檔案代碼中multiInstance.accessCondition(execution)對應的便是此處。其中的mulitiInstance如果是和spring整合了,就是spring管理的bean的id,否則就是流程變量的key。

我遇到的坑在于無論你在多執行個體任務調用taskService.complete(taskId, map)之前往map裡存了什麼,在這個結束條件類裡都是取不到的。

原因在于這裡的回調參數是DelegateExecution類,是整體多執行個體任務的環境,在執行其中一個任務時是取不到的。

可以取到的類是DelegateTask類,是以我們每個執行個體的執行結果處理,應寫在TaskListener類中,而結束條件類用作對TaskListener中的處理結果(包括各種結果的計數等)進行判斷,然後在DelegateExecution的變量中設定輸出方向是通過還是駁回等。這裡判斷函數的傳回時是個boolean,它表示整個多執行個體任務節點是否結束,結束的意思是再進行下一個或其他多執行個體任務,還是将其他多執行個體任務短路掉直接結束,根據方法中setVariable中的值決定之後走向。也就是說boolean不代表接受或駁回,而是代表多執行個體任務節點是否提前結束。

另外計數變量的初值應在多執行個體任務節點錢的連線上綁定的ExecutionListener中設定,因為這才能作用于整個多執行個體任務。如果你在執行多執行個體任務中的某一個時是取不到的。代碼如下:

public class IdeaExecutionListener implements ExecutionListener {

    @Override
    public void notify(DelegateExecution delegateExecution) {
        delegateExecution.setVariable("unrelated",0);
        delegateExecution.setVariable("rejected",0);
    }
}
      

TaskListener示例

public class IdeaTaskListener implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
        //result的值為控制類中taskService.complete(taskId, map)時,map中所設
        String result = (String) delegateTask.getVariable("result");
        //ExecutionListner類中設定的拒絕計數變量
        int rejectedCount = (int)delegateTask.getVariable(“reject”);
        if(“reject”.equals(result)){
            //拒絕
            delegateTask.setVariable("rejected", ++rejectedCount);
        }
    }
      

另附判斷結果類中流程引擎自帶可用變量:

1.nrOfInstances 該會簽環節中總共有多少個執行個體