前言
工作快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整合
包括字型配置、自定義全域性事件監聽、流程定義自動部署開關配置