概述

在这一节,我们将创建一个 Activit 工作流,并启动这个流程,主要包含以下几个步骤:

  1. 定义流程,按照 BPMN 的规范,使用流程定义工具,用流程符号把整个流程描述出来

  2. 部署流程,把画好的流程定义文件,加载到数据库中,生成表的数据

流程设计器的使用

在 resources 目录下创建一个 bpmn 目录,用来存放流程定义文件。选中 bpmn 目录,点击菜单 New -> New Activity 6.x BPMN 2.x file,创建一个 *.bpmn20.xml。选中该文件,右键 view BPMN(Activity ) Diagram,可以看到 BPMN-Activiti-Diagram 流程设计页面。在该页面右键,可以在菜单选择图形,拖拽图形,连线,即可完成流程设计图

连线的时候,要选中图形,这时在图形的右上角会出现一个箭头符号。双击选中箭头符号,右键按住不放即可拉长完成连线

选中一个图形,下方会出现一个属性栏,以创建出差申请为例,这里只填任务名称和负责人

流程部署

流程部署就是将在设计器中定义的流程部署到 activiti 数据库中,Activiti 提供了多种部署流程的方式,包括自动部署、classpath 部署、输入流部署、zip/bar 部署和上传部署等方式,下面分别进行介绍:

1. 自动部署

Activiti7 可以自动部署流程,前提是在 resources 目录下,创建一个新的目录 processes,用来放置 bpmn 文件

2. classpath 部署

classpath 部署方式为采用代码进行部署,使用 Java 代码实现如下:

public class ActivitDemo {

    @Test
public void testDeployment() {
// 1. 创建 ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 使用 service 进行流程部署,即把 bpmn 部署到数据库,并定义流程的名称
Deployment deploy = repositoryService.createDeployment()
// 定义流程资源名称
.name("出差申请流程")
// 加载待部署的资源,可以多次引用
.addClasspathResource("bpmn/evection.bpmn20.xml")
// 完成部署
.deploy();
}
}

3. 输入流部署

Activiti 提供了按输入流(InputStream)方式部署资源,输入流的来源可以有多种,例如本地计算机、classpath 读取、网络读取方式等,下面是读取本地计算机方式进行部署方式的示例代码

public class ActivitDemo {

    @Test
public void testDeployment() {
// 1. 创建 ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 获取输入流
String filePath = "D:/workflow/bpmn/evection.bpmn20.xml";
FileInputStream fileIns = new FileInputStream(filePath);
// 4. 使用 service 进行流程部署
Deployment deploy = repositoryService.createDeployment()
.name("出差申请流程")
.addInputStream("bpmn/evection.bpmn20.xml", fileIns)
.deploy();
}
}

4. zip/bar 部署

将流程资源文件压缩成 zip 包进行部署,同样采用流的方式

public void deployProcessByZip() {
// 1. 获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 流程部署
InputStream inputStream = this.getClass()
.getClassLoader()
.getResourceAsStream("bpmn/evection.zip");
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
repositoryService.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
}

5. 按字符串方式部署

采用字符串方式进行部署,实际是把一个字符串转换为字节流后进行部署,也为开发人员提供了多一种部署方式

public void deployProcessByStr() {
// 1. 获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 构建字符串
String str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><definitions>...</definitions>"
// 4. 流程部署
repositoryService.createDeployment()
.name("出差申请流程")
.addStr("bpmn/evection.bpmn20.xml", str)
.deploy();
}

采用字符串进行部署的优点是可以通过用户界面定义一个流程,然后进行部署,或者在测试时,直接将流程代码写入程序,进行流程部署

6. 动态 BPMN 模型部署

通过在程序中动态生成流程模型方式进行部署,动态创建 BPMN,需要在程序中指定每一个元素,并给出元素间的关系,最后将这些元素整合为一个完整的 BPMN

public void testDeploymentByBPMN() {
// 1. 创建 BPMN 模型实例
BpmnModel bpmnModel = new BpmnModel();
// 2. 创建开始事件
StartEvent startEvent = new StartEvent();
startEvent.setId("startEvent");
startEvent.setName("动态创建开始节点");
// 3. 创建用户任务
UserTask userTask = new UserTask();
userTask.setId("userTask1");
userTask.setName("用户任务节点1");
// 4. 创建结束事件
EndEvent endEvent = new EndEvent();
endEvent.setId("endEvent");
endEvent.setName("动态创建结束节点");
// 5. 定义连接
ArrayList<SequenceFlow> sequenceFlows = new ArrayList<>();
ArrayList<SequenceFlow> toEnd = new ArrayList<>(); SequenceFlow s1 = new SequenceFlow();
s1.setId("sequenceFlow1");
s1.setName("开始节点指向用户任务节点");
s1.setSourceRef("startEvent");
s1.setTargetRef("userTask1");
sequenceFlows.add(s1);
SequenceFlow s2 = new SequenceFlow();
s2.setId("sequenceFlow2");
s2.setName("用户任务节点指向结束节点");
s2.setSourceRef("userTask1");
s2.setTargetRef("endEvent");
toEnd.add(s2); startEvent.setOutgoingFlows(sequenceFlows);
userTask.setOutgoingFlows(toEnd);
userTask.setIncomingFlows(sequenceFlows);
endEvent.setIncomingFlows(toEnd); Process process = new Process();
process.setId("process1");
process.setName("test");
process.addFlowElement(startEvent);
process.addFlowElement(s1);
process.addFlowElement(userTask);
process.addFlowElement(s2);
process.addFlowElement(endEvent);
bpmnModel.addProcess(process);
new BpmnAutoLayout(bpmnModel).execute();
// 6. 部署
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deploy = repositoryService.createDeployment()
.name("出差申请流程")
.addBpmnModel("evection.bpmn20.xml", bpmnModel)
.deploy();
}

7. 相关数据表分析

流程部署后,流程相关的资源全部以数据流的形式存储到数据表中,实际运行中,流程的处理都是通过调用数据表中的相关资源进行处理,下面介绍流程相关的数据表:

  • act_re_deployment

    流程部署表,用于存放流程定义的部署信息,部署一个流程就会增加一条记录

  • act_re_procdef

    流程定义表,用于存放流程定义的属性信息,和 act_re_deployment 是一对多的关系,act_re_procdef 表可以有多条记录,每条记录对应 act_re_deployment 中的一条记录

  • act_ge_bytearray

    资源文件表,部署流程时,会将 BPMN 流程定义文件保存为一条记录,如果部署的流程还包括其他资源,也会增加相应的记录,例如 png 图片文件

Activiti 学习(二)—— Activiti 流程定义和部署的更多相关文章

  1. Activiti学习笔记3 — 流程定义

    一.创建流程引擎对象 private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 二.发布一个流程 ...

  2. activiti学习6:启动流程后动态获取流程图

    目录 activiti学习6:启动流程后动态获取流程图 一.绘图原理 二.根据流程定义id绘图 三.根据流程实例id绘图 3.1 基本原理 3.2 当前节点的获取 3.3 走过的节点的获取 3.4 绘 ...

  3. activiti学习5:开启流程和流程前进

    目录 activiti学习5:开启流程和流程前进 一.流程和任务的关系 二.开启流程 2.1根据流程定义key开启流程 三.查询用户任务 3.1 TaskQuery 四.完成任务 activiti学习 ...

  4. Activiti学习笔记4 — 流程实例化

    1.创建流程引擎对象 private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); 2.启动流程 流程 ...

  5. C++ template学习二 类模板定义及实例化

    一个类模板(也称为类属类或类生成类)允许用户为类定义一种模式,使得类中的某些数据成员.默写成员函数的参数.某些成员函数的返回值,能够取任意类型(包括系统预定义的和用户自定义的). 如果一个类中数据成员 ...

  6. Struts2框架学习(二)——访问流程及架构

    1.Struts2的执行流程 从客户端发送请求过来,先经过前端控制器(核心过滤器StrutsPrepareAndExecuteFilter)过滤器中执行一组拦截器(一组拦截器就会完成部分功能代码),拦 ...

  7. ballerina 学习二十六 项目docker 部署&& 运行(二)

    ballerina 从发布,到现在官方文档的更新也是很给力的,同时也有好多改进,越来越好用了 可以参考官方文档 https://ballerina.io/learn/by-guide/restful- ...

  8. ballerina 学习二十五 项目docker 部署&& 运行

    ballerina 官方提供了docker 的runtime,还是比较方便的 基本项目创建 使用cli创建项目 按照提示操作就行 ballerina init -i 项目结构 添加了dockerfil ...

  9. Activiti学习笔记目录

    1.Activiti学习笔记1 — 下载与开发环境的配置: 2.Activiti学习笔记2 — HelloWorld: 3.Activiti学习笔记3 — 流程定义: 4.Activiti学习笔记4 ...

随机推荐

  1. 使用 Assimp 库加载 3D 模型

    前言 要想让自己的 3D 之旅多一点乐趣,肯定得想办法找一些有意思一点的 3D 模型.3D 模型有各种各样的格式,obj的,stl的,fbx的等等不一而足.特别是 obj 格式的 3D 模型,完全是纯 ...

  2. 用传纸条讲 HTTPS

    我和小宇早恋了,上课的时候老说话. 老师把我们的座位分得很远,我在第一排,她在最后一排,我们中间隔了很多人. 但我们还是想通过传纸条的方式交流. 我们中间的那些同学,虽然坏心思比较多,但好在可以保证将 ...

  3. 软件或jar包版本的小知识---Beta版、Final版、Free版等

    对于各种软件或jar包,其后面总有不同的"尾巴",如: 等,刚开始接触的肯定有些不知道.那么他们到底代表什么意思呢? 0.Release:发布版 1.Beta版:产品发布之前的测试 ...

  4. Java多线程间的数据共享

    下面的程序演示了一个对象被两个线程访问的方法,"monitor.gotMessage();"这一句虽然是monitor对象的方法,但却是运行在"MyObject" ...

  5. repeatedly function in Clojure

    user=> (doc repeatedly) clojure.core/repeatedly ([f] [n f]) Takes a function of no args, presumab ...

  6. 附件携马之CS免杀shellcode过国内主流杀软

    0x01 写在前面 其实去年已经写过类似的文章,但是久没用了,难免有些生疏.所谓温故而知新,因此再详细的记录一下,一方面可以给各位看官做个分享,另一方面等到用时也不至于出现临阵磨枪的尴尬场面. 0x0 ...

  7. NOIP 模拟 $14\; \text{队长快跑}$

    题解 \(by\;zj\varphi\) 一道很妙的 \(dp\) 题,方程状态不好设置,细节也不少 看到数据范围,直接想离散化 设 \(f_{i,j}\) 表示处理完前 \(i\) 个水晶,其中摧毁 ...

  8. Windows 10 - View SIM Card Number

     If your device isn't running Windows 10, refer to the Windows 8 instructions. From the Windows desk ...

  9. C++CLR类库封装Native类库并用C#调用 - 草稿

    1.创建Native类库 新建项目->其他语言->Visual C++->Win32控制台应用程序->DLL     添加头文件       添加源文件       选择生成路 ...

  10. qt 中回调函数的实现

    在QT中回调函数主要可以实现多态性,通过回调函数可以动态处理一些操作.在多线程中,当同时需要处理多个事务的时候,显然你会去创建多个线程类然后实例化,这显然会增加开发工作,当我们在线程类中加入一个回调函 ...