工作流引擎之activiti6流程节点自由跳转实现
在中国式的流程需求中,诸如驳回,退回功能需要进行流程跳转,比如领导审批不通过,退回到申请人。这种中国式的流程需求,可以通过以下三种方式实现
1、通过流程图设计,新增一条驳回连接线,并在连接中配置一些条件进行跳转。通常业务口更希望不需要再额外添加连接线就能实现跳转。
2、动态修改流程定义环节的连线,然后执行跳转,完成后再恢复流程定义。 这种方法可以实现动态跳转,不需要修改Activiti自身执行,但是会动态修改系统中的流程定义缓存对象。理论上这会出现一个多线程下,全局变量不安全的问题。单个Activiti流程引擎中,流程定义缓存对象是被所有线程共用的,当一个应用服务器同时收到两个不同流程实例、同个流程定义、同个环节的任务提交请求。a要求驳回,所以该线程动态修改了流程定义;与此同时,b要求正常流转,但是执行过程中,依据的流程定义已被修改,可能导致b也走向了驳回。
activiti6实现节点自由跳转
1、通过直接操作数据库进行修改,这种方法不推荐,容易出错。
2、通过自定义的command进行实现org.activiti.engine.impl.interceptor.Command接口
通过自定义的command进行实现:
@Override
public Void execute(CommandContext commandContext) {
System.out.println("跳转到目标流程节点:" + targetFlowNodeId);
ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
// 获取当前任务的来源任务及来源节点信息
TaskEntity taskEntity = taskEntityManager.findById(curTaskId);
ExecutionEntity executionEntity = executionEntityManager.findById(taskEntity.getExecutionId());
Process process = ProcessDefinitionUtil.getProcess(executionEntity.getProcessDefinitionId());
// 删除当前节点
taskEntityManager.deleteTask(taskEntity, "", true, true);
// 获取要跳转的目标节点
FlowElement targetFlowElement = process.getFlowElement(targetFlowNodeId);
executionEntity.setCurrentFlowElement(targetFlowElement);
ActivitiEngineAgenda agenda = commandContext.getAgenda();
agenda.planContinueProcessInCompensation(executionEntity);
return null;
}
/**
* 跳转到指定流程节点
*
* @param curTaskId
* @param targetFlowNodeId
* 指定的流程节点ID 比如跳转<endEvent id="endevent1" name="End"></endEvent> ,则targetFlowNodeId为endevent1
*/
public static void jump2TargetFlowNode(String curTaskId, String targetFlowNodeId) {
managementService.executeCommand(new Jump2TargetFlowNodeCommand(curTaskId, targetFlowNodeId));
}
上述跳转命令类的缺陷
只适用于常规节点的跳转,不支持分支节点的跳转、多实例节点的跳转以及并行节点的跳转。
流程实例和执行实例架构图:
activitiEngineAgenda.planContinueProcessInCompensation(executionEntity);
当前节点是普通节点executionEntity:指的是执行实例(左图)
当前节点是多实例节点executionEntity:指的是执行实例(执行实例1、执行实例2、执行实例3的父执行实例)(右图)
activitiEngineAgenda.planContinueProcessInCompensation(executionEntity);
Activiti中国社区交流群:839915498