工做快2年的小白,若有錯誤,懇請你們批評指點,這也是開始寫博客的一個初衷,可以在分享互動、知識梳理中進步。
以前工做的項目使用activiti5進行企業流程系統開發,如今這份工做也開始須要流程開發,瞭解到activiti6扔掉了原來的pvm,直接針對bpmn進行處理,性能有了必定的提高;也有看到flowable6,雖然說是activiti原班人馬出來的,可是實在太新了、用的人也少,小白不敢輕易下手,因而選擇了activiti6。說了好多廢話。。正題正題java
最爲安全可靠,不修改Activiti自身執行和流程定義對象,可是對於中國式流程的功能需求(駁回、回退等),常常是要求在沒有連線的狀況下完成跳轉,靈活性不夠。spring
Activiti5中實現,文中第二種
Activiti6中實現
這種方法能夠實現動態跳轉,不須要修改Activiti自身執行,可是會動態修改系統中的流程定義緩存對象。理論上這會出現一個多線程下,全局變量不安全的問題。單個Activiti流程引擎中,流程定義緩存對象是被全部線程共用的,當一個應用服務器同時收到兩個不一樣流程實例、同個流程定義、同個環節的任務提交請求。a要求駁回,因此該線程動態修改了流程定義;與此同時,b要求正常流轉,可是執行過程當中,依據的流程定義已被修改,可能致使b也走向了駁回。緩存
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實現自由跳轉的介紹。後面會再繼續介紹服務器
即處理人小王完成環節A的任務(id=6000)後,流程走到下一環節B生成任務(id=6004),任務(id=6004)處理人小張審覈不經過執行駁回,流程流轉回環節A,環節A從新生成一條id=6000的待處理人爲小王的任務。多線程
包括字體配置、自定義全局事件監聽、流程定義自動部署開關配置性能