Activiti6實現自由跳轉

坐死等吃發表於2018-03-23

前言

工作快2年的小白,如有錯誤,懇請大家批評指點,這也是開始寫部落格的一個初衷,能夠在分享互動、知識梳理中進步。
之前工作的專案使用activiti5進行企業流程系統開發,現在這份工作也開始需要流程開發,瞭解到activiti6扔掉了原來的pvm,直接針對bpmn進行處理,效能有了一定的提升;也有看到flowable6,雖說是activiti原班人馬出來的,但是實在太新了、用的人也少,小白不敢輕易下手,於是選擇了activiti6。說了好多廢話。。正題正題

Activiti實現跳轉的方式有三種:

1.流程圖配置連線,正常流轉

最為安全可靠,不修改Activiti自身執行和流程定義物件,但是對於中國式流程的功能需求(駁回、回退等),經常是要求在沒有連線的情況下完成跳轉,靈活性不夠。

2.動態修改流程定義環節的連線,然後執行跳轉,完成後再恢復流程定義

Activiti5中實現,文中第二種
Activiti6中實現
這種方法可以實現動態跳轉,不需要修改Activiti自身執行,但是會動態修改系統中的流程定義快取物件。理論上這會出現一個多執行緒下,全域性變數不安全的問題。單個Activiti流程引擎中,流程定義快取物件是被所有執行緒共用的,當一個應用伺服器同時收到兩個不同流程例項、同個流程定義、同個環節的任務提交請求。a要求駁回,所以該執行緒動態修改了流程定義;與此同時,b要求正常流轉,但是執行過程中,依據的流程定義已被修改,可能導致b也走向了駁回。

3.直接指定當前流程例項執行所選的環節

Activiti5中實現
Activiti5中實現,文中第一種
這種方法即可以實現動態跳轉,又沒有動態修改流程定義帶來的不安全問題,而activiti6中因為pvm下的包都刪了,執行計劃的程式碼也進行了改造,原來的方法就不可用了。沒找到相關介紹,自己根據原先的思路,學習Activiti6原始碼,找到了實現的方法,下面提供程式碼。

//跳轉方法
public void jump(String taskId){
        //當前任務
        Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult();
        //獲取流程定義
        Process process = repositoryService.getBpmnModel(currentTask.getProcessDefinitionId()).getMainProcess();
        //獲取目標節點定義
        FlowNode targetNode = (FlowNode)process.getFlowElement("startTask");
        //刪除當前執行任務
        String executionEntityId = managementService.executeCommand(new DeleteTaskCmd(currentTask.getId()));
        //流程執行到來源節點
        managementService.executeCommand(new SetFLowNodeAndGoCmd(targetNode, executionEntityId));
    }
------------------
//刪除當前執行時任務命令,並返回當前任務的執行物件id
//這裡繼承了NeedsActiveTaskCmd,主要時很多跳轉業務場景下,要求不能時掛起任務。可以直接繼承Command即可
public class DeleteTaskCmd extends NeedsActiveTaskCmd<String> {
    public DeleteTaskCmd(String taskId){
        super(taskId);
    }
    public String execute(CommandContext commandContext, TaskEntity currentTask){
        //獲取所需服務
        TaskEntityManagerImpl taskEntityManager = (TaskEntityManagerImpl)commandContext.getTaskEntityManager();
        //獲取當前任務的來源任務及來源節點資訊
        ExecutionEntity executionEntity = currentTask.getExecution();
        //刪除當前任務,來源任務
        taskEntityManager.deleteTask(currentTask, "jumpReason", false, false);
        return executionEntity.getId();
    }
    public String getSuspendedTaskException() {
        return "掛起的任務不能跳轉";
    }
}
------------------
//根據提供節點和執行物件id,進行跳轉命令
public class SetFLowNodeAndGoCmd implements Command<Void> {
    private FlowNode flowElement;
    private String executionId;
    public SetFLowNodeAndGoCmd(FlowNode flowElement,String executionId){
        this.flowElement = flowElement;
        this.executionId = executionId;
    }

    public Void execute(CommandContext commandContext){
        //獲取目標節點的來源連線
        List<SequenceFlow> flows = flowElement.getIncomingFlows();
        if(flows==null || flows.size()<1){
            throw new ActivitiException("回退錯誤,目標節點沒有來源連線");
        }
        //隨便選一條連線來執行,時當前執行計劃為,從連線流轉到目標節點,實現跳轉
        ExecutionEntity executionEntity = commandContext.getExecutionEntityManager().findById(executionId);
        executionEntity.setCurrentFlowElement(flows.get(0));
        commandContext.getAgenda().planTakeOutgoingSequenceFlowsOperation(executionEntity, true);
        return null;
    }
}

最後

以上就是對Activiti6實現自由跳轉的介紹。後面會再繼續介紹

1.以上述自由跳轉為基礎實現不改變原先任務id的駁回

即處理人小王完成環節A的任務(id=6000)後,流程走到下一環節B生成任務(id=6004),任務(id=6004)處理人小張稽核不通過執行駁回,流程流轉回環節A,環節A重新生成一條id=6000的待處理人為小王的任務。

2.java類方式進行Activiti6配置、spring整合

包括字型配置、自定義全域性事件監聽、流程定義自動部署開關配置

相關文章