Activiti 学习(四)—— Activiti 结合实际业务
流程实例
流程实例(ProcessInstance)代表流程定义的执行实例。一个流程实例包括了所有的运行节点。我们可以利用这个对象来了解当前流程实例的进度等信息。例如:用户或程序按照流程定义内容发起一个流程,这就是一个流程实例
流程定义和流程实例的图解:
启动流程实例并添加 BusinessKey(业务标识)
流程定义部署在 activiti 后,就可以在系统中通过 activiti 去管理该流程的执行,执行流程表示流程的一次执行
比如部署系统出差流程后,如果某用户要申请出差这时就需要执行这个流程,如果另外一个用户也要申请出差则也需要执行该流程,每个执行互不影响,每个执行是单独的流程实例
启动流程实例时,指定的 businesskey,就会在 act_ru_execution 流程实例的执行表中存储businesskey
Businesskey,业务标识,通常为业务表的主键,业务标识和流程实例一一对应。业务标识来源于业务系统。存储业务标识就是根据业务标识来关联查询业务系统的数据
比如:出差流程启动一个流程实例,就可以将出差单的 id 作为业务标识存储到 activiti 中,将来查询 activiti 的流程实例信息就可以获取出差单的 id 从而关联查询业务系统数据库得到出差单信息
/**
* 添加业务 key 到 Activiti 的表
*/
@Test
public void addBusinessKey() {
// 1. 获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 3. 启动流程,添加 BusinessKey
ProcessInstance instance = runtimeService.startProcessInstanceByKey("evection", "1001");
// 4. 输出
System.out.println("businessKey: " + instance.getBusinessKey());
}
流程定义的其他操作
1. 流程定义查询
查询流程相关信息,包含流程定义,流程部署,流程定义版本
public void queryProcessDefinition() {
// 1. 获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 查询当前所有的流程定义,返回流程定义信息的集合
ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
List<ProcessDefinition> definitions = definitionQuery.processDefinitionKey("evection")
.orderByProcessDefinitionVersion() // 进行排序
.desc() // 倒序
.list();
// 4. 输出信息
for (ProcessDefinition definition : definitions) {
System.out.println("流程定义 id = " + definition.getId());
System.out.println("流程定义名称 = " + definition.getName());
System.out.println("流程定义 key = " + definition.getKey());
System.out.println("流程定义版本 = " + definition.getVersion());
}
}
2. 流程定义删除
public void deleteDeployment() {
// 1. 获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 通过部署 id 删除流程部署信息,如果该流程定义已有流程实例启动则删除时出错
String deploymentId = "2501";
repositoryService.deleteDeployment(deploymentId);
// 设置 true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置 false 非级别删除方式
// repositoryService.deleteDeployment(deploymentId, true);
}
3. 流程资源下载
我们把流程资源文件上传到数据库,如果其他用户想要查看这些资源文件,可以从数据库下载资源文件
/**
* 下载资源文件,使用 Activiti 提供的 api 下载资源文件,保存到文件目录
*/
public void getDeployment() throws IOException {
// 1. 获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 获取查询对象 ProcessDefinitionQuery,查询流程定义信息
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("evection")
.singleResult();
// 4. 通过流程定义信息,获取部署 id
String deploymentId = processDefinition.getDeploymentId();
// 5. 通过 RepositoryService,传递部署 id 参数,读取资源信息
InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
// 6. 保存资源文件
File file = new File("g:/evectionFlow.bpmn");
FileOutputStream outputStream = new FileOutputStream(file);
IOUtils.copy(bpmnInput, outputStream);
bpmnInput.close();
outputStream.close();
}
4. 历史记录查询
即使流程定义已经删除了,流程执行的历史信息依然保存在 activiti 的 act_hi_* 相关的表中,我们还是可以查询流程执行的历史信息
public void findHistoryInfo() {
// 1. 获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 HistoryService
HistoryService historyService = processEngine.getHistoryService();
// 3. 获取 actinst 表的查询对象
HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
// 4. 查询 actinst 表
instanceQuery.processInstanceId("5001");
instanceQuery.orderByHistoricActivityInstanceStartTime();
// 5. 查询所有内容
List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
// 6. 输出
for (HistoricActivityInstance hi : activityInstanceList) {
System.out.println(hi.getActivityId());
System.out.println(hi.getActivityName());
System.out.println(hi.getProcessDefinitionId());
System.out.println(hi.getProcessInstanceId());
System.out.println("----------------------------");
}
}
5. 流程的挂起与激活
某些情况可能由于流程变更需要将当前运行的流程暂停而不是直接删除,流程暂停后将不会继续执行。
/**
* 全部流程实例的挂起和激活
*/
@Test
public void suspendAllProcessInstance() {
// 1. 获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 查询流程定义
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("evection").singleResult();
// 4. 获取当前流程定义的实例是否都是挂起状态
boolean suspended = processDefinition.isSuspended();
// 5. 获取流程定义的 id
String definitionId = processDefinition.getId();
// 6. 如果是挂起,改为激活状态,如果是激活状态,改为挂起状态
if (suspended) {
repositoryService.activateProcessDefinitionById(definitionId, true, null);
} else {
repositoryService.suspendProcessDefinitionById(definitionId, true, null);
}
}
/**
* 挂起或激活单个流程实例
*/
@Test
public void suspendSingleProcessInstance() {
// 1. 获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取 RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 3. 得到当前流程实例的暂停状态
ProcessInstance instance = runtimeService.createProcessInstanceQuery().processInstanceId("27501").singleResult();
boolean suspended = instance.isSuspended();
// 4. 获取流程实例 id
String instanceId = instance.getId();
// 5. 如果是挂起,改为激活状态,如果是激活状态,改为挂起状态
if (suspended) {
runtimeService.activateProcessInstanceById(instanceId);
} else {
runtimeService.suspendProcessInstanceById(instanceId);
}
}
Activiti 学习(四)—— Activiti 结合实际业务的更多相关文章
- activiti学习资料(架构描述)
Activiti学习资料 Activiti是业界很流行的java工作流引擎,关于Activiti与JBPM5的关系和如何选择不是本文要讨论的话题,相关内容可以baidu一下.Activiti从架构角度 ...
- Activiti 学习笔记记录(二)
上一篇:Activiti 学习笔记记录 导读:对于工作流引擎的使用,我们都知道,需要一个业务事件,比如请假,它会去走一个流程(提交申请->领导审批---(批,不批)---->结束),Act ...
- activiti学习2:示例工程activiti-explorer.war的使用
目录 activiti学习2:示例工程activiti-explorer.war的使用 一.搭建开发环境 二.运行示例工程 三.示例工程功能演示 1. 创建流程图 2. 部署流程图 3. 启动流程 4 ...
- activiti学习笔记一
activiti学习笔记 在讲activiti之前我们必须先了解一下什么是工作流,什么是工作流引擎. 在我们的日常工作中,我们会碰到很多流程化的东西,什么是流程化呢,其实通俗来讲就是有一系列固定的步骤 ...
- 【Activiti学习之一】Activiti入门
环境 JDK1.7 MySQL5.6 Tomcat7 Eclipse-Luna activiti 6.0 一.概念1.工作流(Workflow):是一系列相互衔接.自动进行的业务活动或任务.采用工作流 ...
- activiti学习6:启动流程后动态获取流程图
目录 activiti学习6:启动流程后动态获取流程图 一.绘图原理 二.根据流程定义id绘图 三.根据流程实例id绘图 3.1 基本原理 3.2 当前节点的获取 3.3 走过的节点的获取 3.4 绘 ...
- activiti学习5:开启流程和流程前进
目录 activiti学习5:开启流程和流程前进 一.流程和任务的关系 二.开启流程 2.1根据流程定义key开启流程 三.查询用户任务 3.1 TaskQuery 四.完成任务 activiti学习 ...
- activiti学习4:流程文件的部署
activiti学习4:流程文件的部署 用bpmn规范定义好一个流程得到流程定义文件后,需要把该文件部署到activiti的数据库后,这个流程才可以使用. activiti中和流程定义相关的操作都需要 ...
- activiti学习3:流程引擎对象和流程引擎配置对象
目录 activiti学习3:流程引擎对象和流程引擎配置对象 一.activiti的简单使用流程 二.流程引擎配置对象ProcessEngineConfiguration的介绍 三.activiti配 ...
- activiti学习1:开发环境的搭建
activiti学习1:开发环境的搭建 本文中使用maven+eclipse搭建activiti-5.14的开发环境 一.创建maven工程 创建一个普通的java工程,pom文件的内容如下 < ...
随机推荐
- OpenFaaS实战之八:自制模板(maven+jdk8)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- DVWA靶场练习-暴力破解
一.暴力破解 (Brute Force) 暴力破解是Web安全领域的一个基础技能,破解方法论为:构建常见用户名及弱口令 因此需要好的字典,对应破解场景构建特定的用户名密码,以及还需要具有灵活编写 ...
- 腾讯开源:Kotlin 高性能特效动画组件!
先看一下效果展示: 1. VAP VAP(Video Animation Player)是企鹅电竞开发,用于播放酷炫动画的实现方案. 相比Webp, Apng动图方案,具有高压缩率(素材更小).硬件解 ...
- RedisTemplate连接不释放、Redis断线不重连问题、Redis连接数高飙升
使用RedisTemplate操作Redis数据,但遇到网络断线后不会重新连接 毫无头绪 一顿捣鼓 最终解决 整理如下 帮助更多的人 1.起因 使用RedisTemplate 配置 开启了事务 ena ...
- Run Clojure Script with External Dependencies without leiningen
The normal way of deploy clojure files is using leiningen. But if we have no leiningen, or the scrip ...
- MySQL索引篇之索引存储模型
本文重点介绍下索引的存储模型 二分查找 给定一个1~100的自然数,给你5次机会,你能猜中这个数字吗? 你会从多少开始猜? 为什么一定是50呢?这个就是二分查找的一种思想,也叫折半查找,每 ...
- Qt列表等控件实现平滑滚动&deepin启动器存在的问题
Qt列表等控件实现平滑滚动 Qt自带的的列表控件是不能平滑滚动的,但如果滚动速度快的话很容易引起视线丢失,体验效果很差.本篇主要讲述如何在Qt中对列表控件加入平滑滚动.文中以QScrollArea控件 ...
- kali虚拟机安装VMTools、更新源、安装docker、配置sqli-labs
一.安装VMTools: 传送门:关于安装VMTools 跟其他版本的虚拟机安装VMTools没什么区别,也得连网(我是kali用dhcp开nat模式) 之后按照上面的链接根据博主的步骤一步一步来即可 ...
- NOIP 模拟 $25\; \rm string$
题解 \(by\;zj\varphi\) 考虑对于母串的每个字符,它在匹配串中有多少前缀,多少后缀. 设 \(f_i\) 表示 \(i\) 位置匹配上的前缀,\(g_i\) 为后缀,那么答案为 \(\ ...
- SSM自学笔记(七)
14.MyBatis的多表操作 1.MyBatis的多表操作 1.1 一对一查询 一对一查询的模型 用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对一查询的需求:查询一个订单 ...