activity多实例节点任意跳转

前言

上一篇我们简单演示了单实例节点跳转的过程,在实际业务场景中,多实例节点的跳转也是一种常见的跳转场景,举例来说,当前的节点配置的是会签,即多个实例任务的节点,需要从当前节点跳出去该怎么办呢?或者说从某一个单实例节点再跳入到多实例节点,又该如何实现呢?activity对于这样的场景也提供了解决方案

问题解决思路

想必还记得我们在之前的篇章中谈到的那个流程实例跳转过程中的3级实例树吧?以多实例节点跳出为例

  • 需要的参数,任务ID、目标节点
  • 判断当前的节点是否是多实例任务节点
  • 获取二级执行实例信息
  • 删除二级实例下面的所有三级实例节点
  • 将二级执行实例是否是多实例根节点字段只为false。因为跳出去之后,二级实例是常规的数据
  • 更新二级执行实例数据
  • 触发二级执行实例开始运转

下面开始我们的演示过程

1、部署并启动流程定义文件

activity多实例节点任意跳转_第1张图片

	//部署
    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deployment =
                repositoryService.createDeployment().addClasspathResource("processes/Jumpinstance.bpmn").name("Jumpinstance").deploy();
        System.out.println(deployment.getId());
        System.out.println(deployment.getName());
    }

    //启动流程
    public static void main(String[] args) {
        String key = "jump-multi";
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        runtimeService.startProcessInstanceByKey(key);
        System.out.println("流程启动");
    }

启动完毕,可以通过数据表观察我们的任务数据
activity多实例节点任意跳转_第2张图片

执行动作表
activity多实例节点任意跳转_第3张图片

2、编写实例任务跳转工具类

和之前的几篇中讲到的一样,要完成任务节点的跳转,我们需要在一个辅助的工具类

public class JumpMultiCmd implements Command, Serializable {

    private String taskId;
    private String targetNodeId;

    public JumpMultiCmd(String taskId, String targetNodeId) {
        this.taskId = taskId;
        this.targetNodeId = targetNodeId;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        //任务执行管理器
        TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
        ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
        TaskEntity taskEntity = taskEntityManager.findById(taskId);
        // 三级的执行实例对象
        String executionId = taskEntity.getExecutionId();
        ExecutionEntity lastSecondExecutionEntity = executionEntityManager.findById(executionId);

        //待跳出的三级执行实例
        ExecutionEntity threeExecutionEntity = executionEntityManager.findById(executionId);
        String processDefinitionId = threeExecutionEntity.getProcessDefinitionId();
        //流程定义对象信息
        Process process = ProcessDefinitionUtil.getProcess(processDefinitionId);
        //节点的元信息对象,封装了节点的元数据,如入线和出线
        Activity flowElement = (Activity) process.getFlowElement(taskEntity.getTaskDefinitionKey());
        //待跳出节点的二级实例对象
        ExecutionEntity secondExecutionEntity = threeExecutionEntity.getParent();
        Object behavior = flowElement.getBehavior();
        //判断当前节点的行为类,即是否多实例任务类型,主要做两件事,删除2级实例下的三级实例,然后重新设置2级实例的信息执行更新操作
        if (behavior instanceof MultiInstanceActivityBehavior) {
            executionEntityManager.deleteChildExecutions(secondExecutionEntity, "jump task", false);
            secondExecutionEntity.setActive(true);
            secondExecutionEntity.setMultiInstanceRoot(false);
            executionEntityManager.update(secondExecutionEntity);
        }else {
            //不是多实例
            taskEntityManager.delete(taskId);
            HistoryManager historyManager = commandContext.getHistoryManager();
            historyManager.recordTaskEnd(taskId, "jump task");
            historyManager.recordActivityEnd(lastSecondExecutionEntity, "jump task");
        }
        //使用agenda驱动实例的继续运转,即跳入到目标节点
        Activity targetFlowElement = (Activity) process.getFlowElement(targetNodeId);
        behavior = targetFlowElement.getBehavior();
        secondExecutionEntity.setCurrentFlowElement(targetFlowElement);
        ActivitiEngineAgenda agenda = commandContext.getAgenda();
        if (!(behavior instanceof MultiInstanceActivityBehavior)) {
            agenda.planContinueMultiInstanceOperation(secondExecutionEntity);
        }else {
            lastSecondExecutionEntity.setCurrentFlowElement(targetFlowElement);
            agenda.planContinueProcessInCompensation(lastSecondExecutionEntity);
        }
        return null;
    }
}

3、多实例节点跳出测试

	public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //传入两个参数 ,任务ID以及目标节点ID
        String targetNodeId = "step2";
        String taskId = "2514";
        processEngine.getManagementService().executeCommand(new JumpMultiCmd(taskId, targetNodeId));
    }

运行上面的代码后,我们再次观察任务表,可以发现,任务直接来到了第二个节点
在这里插入图片描述
执行动作表
activity多实例节点任意跳转_第4张图片

那么,如果我们还要继续从当前节点跳回到原来的多实例节点呢?只需修改一下taskId和targetNodeId即可

	//普通节点跳入多实例
    public static void main(String[] args) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String targetNodeId = "step1";
        String taskId = "5002";
        processEngine.getManagementService().executeCommand(new JumpMultiCmd(taskId, targetNodeId));
    }

运行上述代码,再次观察两张表的数据,任务表可以发现又产生了3条任务数据
activity多实例节点任意跳转_第5张图片

执行动作表
activity多实例节点任意跳转_第6张图片
即通过上面的演示,达到了我们预期的效果,这种节点跳转的实现还是方便灵活而且便于使用,其实主要就是要弄清楚跳转的实现原理,可以重点参考我们开篇的实现思路以及掌握相关API的使用

本篇到此结束,最后感谢观看!

你可能感兴趣的:(activity)