一、流程定义的版本

  当部署流程定义时,数据库中的流程定义会是这个样子:

id key name version
myProcess:1:676 myProcess My important process 1

  如果我们现在部署同一个流程的更新版本(例如修改部分用户任务),且保持流程定义的id不变,那么流程定义表中会包含下面的记录:

id key name version
myProcess:1:676 myProcess My important process 1
myProcess:2:870 myProcess My important process 2

  当调用执行流程时,会使用版本2的流程定义,因为这是这个流程定义的最新版本。

二、流程部署方式

2.1 指定项目内资源文件部署

  比如在resources/下新建资源文件single-task.bpmn20.xml

<?xml version="1.0" encoding="UTF-8"?>
<definitions
       xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
       xmlns:flowable="http://flowable.org/bpmn"
       targetNamespace="Examples">

   <process id="singleTask" name="The One Task Process">
       <startEvent id="theStart" />
       <sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" />
       <userTask id="theTask" name="my task" flowable:assignee="zhangsan" />
       <sequenceFlow id="flow2" sourceRef="theTask" targetRef="theEnd" />
       <endEvent id="theEnd" />
   </process>

</definitions>

  部署示例代码:

 // 资源路径
String path = "single-task.bpmn20.xml";
// 创建部署构建器
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
// 添加资源
deploymentBuilder.addClasspathResource(path);
// 执行部署
deploymentBuilder.deploy();
// 验证部署
long count = repositoryService.createProcessDefinitionQuery().processDefinitionKey("singleTask").count();
// count等于1,则说明部署成功

  只要是在项目class目录下的资源,都可以用这种方式部署。

  这种方式一般用于开发测试阶段,真正的生产环境,是通过与web管理页面交互部署。

2.2 springboot自动部署

  在springboot环境下,resources/processes目录下的任何BPMN 2.0流程定义都会被自动部署。

2.3 接口方式

  实际生产中,我们需要接收前端传回来的流程定义数据,然后更新部署。

  下面我们省去前端访问接口参数的展示,仅演示后端处理代码。

// 从前端接收到的XML字符串
// 此处省去xml具体内容,可参考2.1的single-task.bpmn20.xml示例
// 注意将id定义为singleTask2,以便跟2.1的内容作出区别
String text = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><definitions...</definitions>";
// 创建部署构建器
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
// 执行部署
deploymentBuilder.addString("single-task2.bpmn20.xml", text).deploy();
// 验证部署
long count = repositoryService.createProcessDefinitionQuery().processDefinitionKey("singleTask2").count();
// count等于1,则说明部署成功

2.4 zip压缩包

  当我们需要一次同时部署多个资源时,可以通过zip压缩包的部署方式。

String fileName = "path/multi-task.zip";
ZipInputStream inputStream = new ZipInputStream(new FileInputStream(fileName));

repositoryService.createDeployment()
  .name("multi-task.zip")
  .addZipInputStream(inputStream)
  .deploy();

三、流程管理

  业务系统的第一步,就是需要一个列表可以浏览和管理流程定义。

3.1 获取已部署流程列表

@Autowired
private RepositoryService repositoryService;

public List getDeployList() {
   List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
   return list;
}

3.2 读取流程图片

  显然,管理页面需要显示流程图片的功能。

  Flowable引擎会在流程部署时,自动生成流程图片。

  获取流程图片方法:

ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("singleTask")
.singleResult();

String diagramResourceName = processDefinition.getDiagramResourceName();
InputStream imageStream = repositoryService.getResourceAsStream(
   processDefinition.getDeploymentId(), diagramResourceName);

注意:如果不需要或不希望在部署时生成流程图,可以在流程引擎配置中设置isCreateDiagramOnDeploy参数:

<property name="createDiagramOnDeploy" value="false" />

3.3 读取流程定义的XML

  管理界面可增加“显示流程定义代码”功能,即读取显示流程定义的XML内容。

// 根据processDefinitionId查询
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
// 读取资源流,resourceName为前端传回的资源名称
InputStream stream = repositoryService.getResourceAsStream(pd.getDeploymentId(), resourceName);
//读取到的资源流再返回到前端

3.4 删除部署

  一个流程定义不是通过流程定义ID删除,而是通过流程定义的部署ID删除。在执行删除时,会将和本次部署有关的资源一起删除。

repositoryService.deleteDeployment(deploymentId, true);

四、小结

  本篇介绍了流程定义的版本、部署及管理的使用方法。当然,在实际应用中,还有很多细节需要优化,比如流程定义部署时的去重,分页获取流程列表等等。

Flowable实战(三)流程部署管理的更多相关文章

  1. 2017.2.28 activiti实战--第五章--用户与组及部署管理(三)部署流程及资源读取

    学习资料:<Activiti实战> 第五章 用户与组及部署管理(三)部署流程及资源读取 内容概览:如何利用API读取已经部署的资源,比如读取流程定义的XML文件,或流程对应的图片文件. 以 ...

  2. 2017.2.28 activiti实战--第五章--用户与组及部署管理(二)部署流程资源

    学习资料:<Activiti实战> 第五章 用户与组及部署管理(二)部署流程资源 内容概览:讲解流程资源的读取与部署. 5.2 部署流程资源 5.2.1 流程资源 流程资源常用的有以下几种 ...

  3. 工作流学习——Activiti流程定义管理三步曲 (zhuan)

    http://blog.csdn.net/zwk626542417/article/details/46602419 ***************************************** ...

  4. 2017.2.20 activiti实战--第五章--用户与组及部署管理(一)用户与组

    学习资料:<Activiti实战> 第五章 用户与组及部署管理(一)用户与组 内容概览:讲解activiti中内置的一套用户.组的关系,以及如何通过API添加.删除.查询. 5.1 用户与 ...

  5. Spring管理流程部署——Activiti

    pom.xml <!-- activit jar 包 --> <dependency> <groupId>org.activiti</groupId> ...

  6. Flowable实战(四)BPMN2.0 启动与结束事件

    一.BPMN2.0   BPMN2.0规范是一个标准,开源框架和不同供应商都遵循这份标准,使得最终用户不会因为依赖专有解决方案,而被供应商"绑架".有了BPMN2.0标准,不同解决 ...

  7. Flowable实战(八)BPMN2.0 任务

      任务是流程中最重要的组成部分.Flowable提供了多种任务类型,以满足实际需求.   常用任务类型有: 用户任务 Java Service任务 脚本任务 业务规则任务 执行监听器 任务监听器 多 ...

  8. 《Apache kafka实战》读书笔记-管理Kafka集群安全之ACL篇

    <Apache kafka实战>读书笔记-管理Kafka集群安全之ACL篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 想必大家能看到这篇博客的小伙伴,估计你对kaf ...

  9. 第一阶段考试:实战Linux系统日常管理

    1. [项目名称] 实战Linux系统日常管理 [项目说明] 1.安装部署rhel系统,组建RAID磁盘阵列. 2.安装nginx 通过脚本编写 nginx服务服务启动脚本 [项目考核技能点] 1.安 ...

随机推荐

  1. epoll 使用详解

    epoll - I/O event notification facility在linux的网络编程中,很长的时间都在使用select来做事件触发.在linux新的内核中,有了一种替换它的机制,就是e ...

  2. WPF将窗口置于桌面下方(可用于动态桌面)

    WPF将窗口置于桌面下方(可用于动态桌面) 先来看一下效果: 界面元素很简单,就一个Button按钮,然后写个定时器,定时更新Button按钮中的内容为当前时间,下面来介绍下原理,和界面组成. 窗口介 ...

  3. [BUUCTF]PWN——roarctf_2019_easy_pwn(详解)

    roarctf_2019_easy_pwn 附件 步骤: 例行检查,64位程序,保护全开 试运行一下程序,看看大概的情况,经典的堆块的菜单 64位ida载入,改了一下各个选项的函数名,方便看程序(按N ...

  4. 2020腾讯犀牛鸟网络安全T-Star高校挑战赛writeup

    签到 浏览器禁用js,在www目录下有 key 命令执行基础 使用 | 可以执行其他命令,在 ../目录下有 key.php cat 一下读出来 你能爆破吗 一开始随便输了个账号的时候不是这个页面,抓 ...

  5. YonBuilder低代码开发实践:4行代码实现跨实体列表数据同步

    提到增.删.改.查等数据维护,后端开发者们再熟悉不过了.传统的数据维护通过操作数据库的方式实现,步骤比较繁琐,需要通过Java代码实现数据库链接,然后编写SQL语句.编写实体,将想要的数据存到相应的数 ...

  6. 删除空行(嵌套)(Power Query 之 M 语言)

    数据源: "姓名""基数""个人比例""个人缴纳""公司比例""公司缴纳"&qu ...

  7. mail如何在linux中发送邮件,使用163邮箱发信。

    如何在linux中发送邮件,使用163邮箱发信.   linux中,可以使用mail命令往外发送邮件,在使用前,只需要指定如下简单配置即可,这里演示用  163.com    邮箱发送至 qq.com ...

  8. jQuery Validate验证(判断)某个字段是否通过验证

    jQuery Validate 默认只能判断整个表单是否验证通过,但是有时候我们需要对某个字段进行判断 ,可以使用以下方法 var bool=$("整个form表单的ID").va ...

  9. 使用mysql查询语句统计数据,如果是null值则赋值为0

    select IFNULL(sum(total_view),0) from 如果统计total_view这列为null ,则返回默认值0

  10. 第47篇-解释执行的Java方法调用native方法小实例

    举个小实例,如下: public class TestJNI { static { // 程序在加载时,自动加载libdiaoyong.so库 System.loadLibrary("dia ...