工作流引擎之activiti6流程节点自由跳转实现

前言

在中国式的流程需求中,诸如驳回,退回功能需要进行流程跳转,比如领导审批不通过,退回到申请人。这种中国式的流程需求,可以通过以下三种方式实现

1、通过流程图设计,新增一条驳回连接线,并在连接中配置一些条件进行跳转。通常业务口更希望不需要再额外添加连接线就能实现跳转。 2、动态修改流程定义环节的连线,然后执行跳转,完成后再恢复流程定义。 这种方法可以实现动态跳转,不需要修改Activiti自身执行,但是会动态修改系统中的流程定义缓存对象。理论上这会出现一个多线程下,全局变量不安全的问题。单个Activiti流程引擎中,流程定义缓存对象是被所有线程共用的,当一个应用服务器同时收到两个不同流程实例、同个流程定义、同个环节的任务提交请求。a要求驳回,所以该线程动态修改了流程定义;与此同时,b要求正常流转,但是执行过程中,依据的流程定义已被修改,可能导致b也走向了驳回。 3、直接指定节点进行跳转,这是本篇介绍的重点

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));
    }

节点自由跳转测试

流程图:

按这个流程图顺序,顺序执行为开始-->员工申请-->经理审批-->人事归档-->结束。当走到员工申请的下一节点时为经理审批,现在我们强行把员工申请的下一节点变成结束节点。

控制台输出

是否跳转指定流程...
yes
请输入要跳转的目标节点ID...
endevent1
Fri Aug 10 16:54:56 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
跳转到目标流程节点:endevent1
Fri Aug 10 16:54:56 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
----------------------------------流程实例流转-----------------------
Fri Aug 10 16:54:56 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
活动ID:232508
流程实例ID:232501
活动名称:Start
办理人:null
开始时间:Fri Aug 10 16:54:39 CST 2018
结束时间:Fri Aug 10 16:54:39 CST 2018
=================================
活动ID:232509
流程实例ID:232501
活动名称:员工申请
办理人:applyUser
开始时间:Fri Aug 10 16:54:39 CST 2018
结束时间:Fri Aug 10 16:54:39 CST 2018
=================================
活动ID:237501
流程实例ID:232501
活动名称:End
办理人:null
开始时间:Fri Aug 10 16:54:56 CST 2018
结束时间:Fri Aug 10 16:54:56 CST 2018
=================================

上述跳转命令类的缺陷

只适用于常规节点的跳转,不支持分支节点的跳转、多实例节点的跳转以及并行节点的跳转

demo地址

https://github.com/lyb-geek/demo-activiti-freeJumpNode

本文分享自微信公众号 - Linyb极客之路(gh_c420b2cf6b47)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-08-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏微信公众号:Java团长

面试的角度诠释Java工程师(二)

反射:反射是Java开发的一类动态相关机制。因为本身Java语言并不是一款动态语言,如果我们想要得到程序动态的效果,因此便引入了反射机制这一概念。

10310
来自专栏张善友的专栏

使用Hystrix提高系统可用性

今天稍微复杂点的互联网应用,服务端基本都是分布式的,大量的服务支撑起整个系统,服务之间也难免有大量的依赖关系,依赖都是通过网络连接起来。 ? (图片来源:htt...

23450
来自专栏Ryan Miao

使用checkstyle来规范你的项目

自从做了程序员,关于格式化的讨论就不曾中断过,到底什么才是正确的,什么才是错误的,到现在也没有完整的定论。但随着时间发展,渐渐衍生出一套规范出来。没有什么绝对的...

30610
来自专栏挖掘大数据

Apache NiFi 简介及Processor实战应用

Apache NiFi是什么?NiFi官网给出如下解释:“一个易用、强大、可靠的数据处理与分发系统”。通俗的来说,即Apache NiFi 是一个易于使用、功能...

2.4K100
来自专栏Spark学习技巧

面试的角度诠释Java工程师(二)

12120
来自专栏即时通讯技术

新手入门:目前为止最透彻的的Netty高性能原理和框架架构解析

Netty 是一个广受欢迎的异步事件驱动的Java开源网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。

3.4K30
来自专栏扎心了老铁

Linux Redis集群搭建与集群客户端实现

硬件环境 本文适用的硬件环境如下 Linux版本:CentOS release 6.7 (Final) Redis版本:3.2.1 Redis已经成功安装,安装...

490130
来自专栏SeanCheney的专栏

爬虫框架整理汇总

58960
来自专栏余林丰

关于日志打印的几点建议以及非最佳实践

  日志的打印在软件开发过程中必不可少,一般分为两个大类: 操作日志 系统日志   操作日志,主要针对的是用户,例如在Photoshop软件中会记录自己操作的步...

46170
来自专栏C/C++基础

Linux下离线手动下载安装C++开发环境

Linux下我们习惯了使用软件包管理器来安装我们需要的软件,比如Red Hat公司的Fedora、RHEL(Red Hat Enterprise Linux)和...

76220

扫码关注云+社区

领取腾讯云代金券