Activiti7-流程初体验
流程符号详解:
创建Activiti工作流的主要步骤包含以下几步:
1. 定义流程。按照BPMN的规范,使用流程定义工具,将整个流程描述出来。
2. 部署流程。把画好的BPMN流程定义文件加载到数据库中,生成相关的表数据。
3. 启动流程。使用java代码来操作数据库表中的内容。
部署请假流程:
整体代码如下:
package com.nanjing;import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricActivityInstanceQuery;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.IOUtils;
import org.junit.Test;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.zip.ZipInputStream;/*** @author :楼兰* @date :Created in 2021/4/7* @description:**/public class ActivitiDemo {/*** 部署流程定义 文件上传方式*/@Testpublic void testDeployment(){
// 1、创建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2、得到RepositoryService实例RepositoryService repositoryService = processEngine.getRepositoryService();
// 3、使用RepositoryService进行部署Deployment deployment = repositoryService.createDeployment().addClasspathResource("leave.bpmn20.xml") // 添加bpmn资源//png资源命名是有规范的。Leave.myleave.png|jpg|gif|svg 或者Leave.png|jpg|gif|svg.addClasspathResource("leave.png") // 添加png资源.name("请假申请流程").deploy();
// 4、输出部署信息System.out.println("流程部署id:" + deployment.getId());System.out.println("流程部署名称:" + deployment.getName());}/*** zip压缩文件上传方式*/@Testpublic void deployProcessByZip() {// 定义zip输入流InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("leave.zip");ZipInputStream zipInputStream = new ZipInputStream(inputStream);// 获取repositoryServiceProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();RepositoryService repositoryService = processEngine.getRepositoryService();// 流程部署Deployment deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).deploy();System.out.println("流程部署id:" + deployment.getId());System.out.println("流程部署名称:" + deployment.getName());}/*** 启动流程实例*/@Testpublic void testStartProcess(){
// 1、创建ProcessEngineProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2、获取RunTimeServiceRuntimeService runtimeService = processEngine.getRuntimeService();
// 3、根据流程定义Id启动流程ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myleave");
// 输出内容System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());System.out.println("流程实例id:" + processInstance.getId());System.out.println("当前活动Id:" + processInstance.getActivityId());}/*** 查询当前个人待执行的任务*/@Testpublic void testFindPersonalTaskList() {
// 任务负责人String assignee = "worker";ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 创建TaskServiceTaskService taskService = processEngine.getTaskService();
// 根据流程key 和 任务负责人 查询任务List<Task> list = taskService.createTaskQuery().processDefinitionKey("myleave") //流程Key.taskAssignee(assignee)//只查询该任务负责人的任务.list();for (Task task : list) {System.out.println("流程实例id:" + task.getProcessInstanceId());System.out.println("任务id:" + task.getId());System.out.println("任务负责人:" + task.getAssignee());System.out.println("任务名称:" + task.getName());}}// 完成任务@Testpublic void completTask(){
// 获取引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取taskServiceTaskService taskService = processEngine.getTaskService();// 根据流程key 和 任务的负责人 查询任务
// 返回一个任务对象Task task = taskService.createTaskQuery().processDefinitionKey("myleave") //流程Key.taskAssignee("worker") //要查询的负责人.singleResult();// 完成任务,参数:任务idtaskService.complete(task.getId());}/*** 查询流程定义*/@Testpublic void queryProcessDefinition(){// 获取引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// repositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();
// 得到ProcessDefinitionQuery 对象ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
// 查询出当前所有的流程定义
// 条件:processDefinitionKey =evection
// orderByProcessDefinitionVersion 按照版本排序
// desc倒叙
// list 返回集合List<ProcessDefinition> definitionList = processDefinitionQuery.processDefinitionKey("myleave").orderByProcessDefinitionVersion().desc().list();
// 输出流程定义信息for (ProcessDefinition processDefinition : definitionList) {System.out.println("流程定义 id="+processDefinition.getId());System.out.println("流程定义 name="+processDefinition.getName());System.out.println("流程定义 key="+processDefinition.getKey());System.out.println("流程定义 Version="+processDefinition.getVersion());System.out.println("流程部署ID ="+processDefinition.getDeploymentId());}}/*** 查询流程实例*/@Testpublic void queryProcessInstance() {// 流程定义keyString processDefinitionKey = "myleave";ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 获取RunTimeServiceRuntimeService runtimeService = processEngine.getRuntimeService();List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().processDefinitionKey(processDefinitionKey)//.list();for (ProcessInstance processInstance : list) {System.out.println("----------------------------");System.out.println("流程实例id:"+ processInstance.getProcessInstanceId());System.out.println("所属流程定义id:"+ processInstance.getProcessDefinitionId());System.out.println("是否执行完成:" + processInstance.isEnded());System.out.println("是否暂停:" + processInstance.isSuspended());System.out.println("当前活动标识:" + processInstance.getActivityId());System.out.println("业务关键字:"+processInstance.getBusinessKey());}}@Testpublic void deleteDeployment() {// 流程部署idString deploymentId = "1";ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 通过流程引擎获取repositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();//删除流程定义,如果该流程定义已有流程实例启动则删除时出错repositoryService.deleteDeployment(deploymentId);//设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式,如果流程
// repositoryService.deleteDeployment(deploymentId, true);}@Testpublic void queryBpmnFile() throws IOException {
// 1、得到引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2、获取repositoryServiceRepositoryService repositoryService = processEngine.getRepositoryService();
// 3、得到查询器:ProcessDefinitionQuery,设置查询条件,得到想要的流程定义ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("myleave").singleResult();
// 4、通过流程定义信息,得到部署IDString deploymentId = processDefinition.getDeploymentId();
// 5、通过repositoryService的方法,实现读取图片信息和bpmn信息
// png图片的流InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
// bpmn文件的流InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
// 6、构造OutputStream流File file_png = new File("/Users/zhou/myleave.png");File file_bpmn = new File("/Users/zhou/leave.bpmn20.xml");FileOutputStream bpmnOut = new FileOutputStream(file_bpmn);FileOutputStream pngOut = new FileOutputStream(file_png);
// 7、输入流,输出流的转换IOUtils.copy(pngInput,pngOut);IOUtils.copy(bpmnInput,bpmnOut);
// 8、关闭流pngOut.close();bpmnOut.close();pngInput.close();bpmnInput.close();}/*** 查看历史信息*/@Testpublic void findHistoryInfo(){
// 获取引擎ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取HistoryServiceHistoryService historyService = processEngine.getHistoryService();
// 获取 actinst表的查询对象HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
// 查询 actinst表,条件:根据 InstanceId 查询,查询一个流程的所有历史信息instanceQuery.processInstanceId("2501");
// 查询 actinst表,条件:根据 DefinitionId 查询,查询一种流程的所有历史信息
// instanceQuery.processDefinitionId("myleave:1:22504");
// 增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
// 查询所有内容List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
// 输出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("<==========================>");}}}
1.部署流程,执行这个方法:testDeployment
也可以通过zip压缩文件上传方式,一次定义多个流程,这里我就不尝试了
2.启动流程实例,执行testStartProcess
一个业务流程部署到activiti后,就可以使用了。例如这个出差申请的流程部署完成 后,就可以启动
一个流程进行一次出差申请了。流程的执行过程主要通过 RuntimeService服务来管理。
3.任务查询
流程启动后,任务的负责人就可以查询自己当前需要处理的待办任务了。
任务相关 的服务都是由TaskService管理。
当前请假流程启动后,就该等待worker用户提交请假申请了。实际中的 请假申请流程应该是从
worker提交请假申请开始,但是在activiti工作流 中,都是从starter事件开始,这个关系要理清楚。
4.流程任务处理
任务负责人查询到代办任务后,可以选择任务进行处理,完成任务。
这个任务完成后,这一个请假流程就推动到了下一个步骤,部门经理审批了。后续
可以用不同的用户来推动流程结束。
其实在完成审批任务的过程中,可以针对这个taskId,进行其他一些补充操作。例 如添加
Comment,添加附件,添加子任务,添加候选负责人等等。具体可以看下 taskService的API。
5.流程定义信息查询
这一步可以查询流程相关信息,包含流程定义,流程部署,流程版本。
6.流程实例信息查询
7.删除流程
注:
1、这里只删除了流程定义,不会删除历史表信息
2、删除任务时,可以选择传入一个boolean型的变量cascade ,表示是 否级联删除。
默认是false,表示普通删除。
如果该流程下存在已经运行的流程,使用普通删除会报错,而级联删除
可以将流程及相关记录全部删除。删除没有完成的流程节点后,就可以
完全删除流程定义信息了。
项目开发中,级联删除操作一般只开放给管理员使用。
由于刚刚已经发起了流程,还没有走完,删除报错
8.流程资源下载
在流程执行过程中,可以上传流程资源文件。我们之前在部署流程时,已经将 bpmn和描述bpmn
的png图片都上传了,并且在流程执行过程中,也可以上传资源 文件。如果其他用户想要查看这些
资源文件,可以从数据库中把资源文件下载下 来。
但是文件是以Blob的方式存在数据库中的,要获取Blob文件,可以使用JDBC来处 理。也可以使用
activiti提供的api来辅助实现。我们这里采用activiti的方式来实现。
注: 在获取资源文件名时,png图片资源的文件名是
processDefinition.getDiagramResourceName(),他来自于ACT_RE_PROCDEF表中的
DGRM_RESOURCE_NAME字段。这个字段 的值是在部署流程时根据文件名后缀判断出来的。
支持的格式为 [ResourceName].[key].[png|jpg|gif|svg]或者[ResourceName]. [png|jpg|gif|svg]
而bpmn文件的文件名是processDefinition.getResourceName(),他 来自于ACT_RE_PROCDEF表
中的RESOURCE_NAME字段。
9.流程历史信息查看
流程的历史信息都保存在activiti的act_hi_*相关的表中,我们可以查询流程执行的历 史信息。
这里需要通过HistoryService来查看相关的历史记录。
注:
1、关于流程历史信息,要注意,在删除流程时,如果是采取级联删 除的方式,那这个历史信息也
会随着一起删除。而普通删除方式不会删 除历史信息。
2、历史信息有不同的种类,具体可以通过historyService构建不同类型 的Query对象来获取结果。
Activiti7-流程初体验相关推荐
- Online开发初体验——Jeecg-Boot 在线设计流程
Online开发--初体验(在线设计流程) 01 在线设计流程 02 在线设计流程和表单对接 03 表单业务申请 演示在线设计流程 演示在线设计流程与表单对接 演示业务OA申请
- 工作流Activiti初体验—流程撤回【二】
已经玩工作流了,打算还是研究一下撤回的功能.但是流程图里面并不带撤回的组件,所以需要自己动态改造一下,还是延续上一个流程继续试验撤回功能.<工作流Activiti初体验[一]> 完整流程图 ...
- 用鸿蒙跑了个 “hello world”!鸿蒙开发初体验
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源 | https://my.oschina.net/u ...
- 深度探索Hyperledger技术与应用之超级账本初体验(附部署代码)
2019独角兽企业重金招聘Python工程师标准>>> 本章零基础地介绍了如何快速体验超级账本搭建的区块链网络,我们先绕过了比较复杂的初始化配置,用官方提供的fabric-sampl ...
- harmonyos能否移植到MCU,HarmonyOS(LiteOs_m) 官方例程移植到STM32初体验
HarmonyOS(LiteOs_m) 官方例程移植到STM32初体验 硬件平台 基于正点原子战舰V3开发板 MCU:STM32F103ZET6 片上SRAM大小:64KBytes 片上FLASH大小 ...
- Windows Embedded CE 6.0开发初体验(二)CE开发环境 收藏
上一篇<Windows Embedded CE 6.0开发初体验>之"嵌入式开发流程": http://blog.csdn.net/aawolf/archive/200 ...
- [Android Studio] 初体验
[Android Studio] 初体验 本人刚开始接触移动开发方面的知识,在很多方面都感觉寸步难行,移动开发这门课程应该是在我一年后学校才会开设,而移动开发所用到的java也是在我下个学期才开始正式 ...
- java代码初体验_第一次Java 8体验
java代码初体验 像世界其他地方一样,我深深地爱上了Slack. 为什么? 原因很多,但主要的原因是它提供了一种围绕通讯而非工具真正构建SDLC流程的新方法. 您认为这些天哪个更常见,杂乱无章的机智 ...
- node.js 初体验
node.js 初体验 2011-10-31 22:56 by 聂微东, 174545 阅读, 118 评论, 收藏, 编辑 PS: ~ 此篇文章的进阶内容在为<Nodejs初阶之express ...
- Windows Embedded CE 6.0开发初体验(一)Windows CE概述
这篇文章的目的并不是介绍Windows Embedded CE开发的方方面面,只是用一个初涉嵌入式领域的软件开发者的视角来介绍Windows CE开发中最常用的概念和知识,解决大家会在实际开发中碰到的 ...
最新文章
- dubbo入门学习笔记之入门demo(基于普通maven项目)
- kerberos 身份认证 简介
- 为什么我启动哪一个tomcat都是启动同一个tomcat(tomcat7)
- 数据集成之主数据管理(转载整理)
- iOS 测试三方 KIF 的那些事
- 这个网站收集了很多杂志的审稿周期和收稿、拒稿意见,值得看看
- python使用sqlalchemy执行sql查询语句
- Android 应用开发(9)---内联复杂的XML资源
- warning: left shift count = width of type
- xcode 调试提示
- 卸载sqlserver2012
- 亿航白鹭落户西安建丝路总部,为“硬科技之都”插上双翼
- 51单片机c语言实训报告总结,单片机实训心得体会
- 国外主机服务有哪些推荐?
- 成都超级计算机中心玻璃,成都超算中心首次亮相
- w7系统出现无法更新服务器,win7系统自动更新选项不能用了的解决方法
- java新手案例_java初学者都要掌握的案例
- Guava之RateLimiter限流
- 抖音数据采集xgorgon算法、device_id算法、xlog算法、protobuffer解密...
- 使用 DolphinScheduler 调度 Kylin 构建