我是一个目录
上篇介绍如何搭建activiti7的环境,这篇介绍流程定义和实例及其部署相关操作
如果需要回忆的,请移步 环境准备
1.流程定义
1.1 绘制流程图
前文中已经安装了绘制流程图的插件,和目录结构,接下来,先在diagram文件夹里面新建一个bpmn文件
如图:
画图的过程我就不赘述了,画成这款式就差不多了。
然后,你可以用截图工具截个图,保存为png文件一起放在diagram里面,我个人喜欢这种方式,方便!当然有其他比较繁琐的方式,就自行探索了。
反正最后弄出一个bpmn文件和一个png文件,这俩配对组合对应一套流程图。相信你能明白!
然后注意每个方框的流程,你左键点击一下,会有一个属性框如下,我框住的部分就是这个流程的处理人,我现在是写死的,后面的文章会再次具体的介绍这里究竟如何使用,现在。。先将就写死方便一些
1.2 简单介绍API和原理机制
1.2.1 API
API | 简介 |
---|---|
RepositoryService | activiti的资源管理类 |
RuntimeService | activiti的流程运行管理类 |
TaskService | activiti的任务管理类 |
HistoryService | activiti的历史管理类 |
ManagerService | activiti的引擎管理类 |
1.2.2 原理机制
先将流程图中每个节点数据读取放去表中
读取表的第一条记录,处理并删除
实现自动化:
1.业务流程图要规范化,要遵守一套标准
2.这个业务流程图本质上是一个xml文件,这样就可以存入索要数据
3.读取业务流程图的过程就是解析xml文件的过程
4.读取一个业务流程图中的结点就相当于解析一个xml结点,进一步将数据插入数据库形成记录
5.将所有节点都读取并存入数据库表
6.后面只要读取mysql表中记录即可,都一条记录就相当于读一个节点
7.业务流程的推进,后面就转化为读表中数据,并处理数据,结束时这一行数据就可以删除
1.3 流程定义部署测试类
public static void main(String[] args){
//main方法用于测试
//1.创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RepositoryService实例
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.进行部署
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday.bpmn") //添加bpmn资源
.addClasspathResource("diagram/holiday.png")
.name("请假申请流程")
.deploy();
//4.输出部署信息
System.out.println(deployment.getName());
System.out.println(deployment.getId());
}
1.4 分析影响的表
act_re_deployment:部署信息
act_re_procdef:这张表就是流程定义表,同时它有一个key,来标识这个流程并区分其他流程
act_ge_bytearray 流程定义的bpmn和png
2. 流程实例
看到这里你可能会有疑惑,流程定义和流程实例啥关系?
流程定义好比Java中的一个类
流程实例好比Java对象,一个流程定义可以new多个流程实例的这种感觉。秒懂?
2.1 启动流程实例
public static void main(String[] args){
//1.得到processEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RunTimeService对象
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.创建流程实例 要知道流程定义的key需要知道
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday");
//4.输出实例的相关信息
System.out.println("流程部署ID:"+processInstance.getDeploymentId());
System.out.println("流程实例ID:"+processInstance.getId());
System.out.println("活动节点ID:"+processInstance.getActivityId());
}
2.2 分析影响的表
act_hi_actinst:已完成活动信息
act_hi_identitylink: 参与者信息
act_hi_procinst:流程实例
act_hi_taskinst:任务实例
act_ru_execution:执行表
act_ru_identitylink:参与者信息
act_ru_task: 任务
3. 任务查询
public static void main(String[] args){
//1.得到ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到TaskService对象
TaskService taskService = processEngine.getTaskService();
//3.根据流程定义key,负责人assignee来实现当前用户的任务列表查询
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey("holiday")
.taskAssignee("zhangsan")
.list();
//4.任务列表展示
for (Task task: taskList){
System.out.println("流程实例id: "+task.getProcessDefinitionId());
System.out.println("任务id: "+task.getId());
System.out.println("任务负责人: "+task.getAssignee());
System.out.println("任务名称: "+task.getName());
}
}
想说的都在代码里了,就不多赘述
4. 任务处理
public static void main(String[] args){
//1.得到ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到TaskService对象
TaskService taskService = processEngine.getTaskService();
//3.处理任务,结合当前用户任务列表查询操作的话,任务5005
taskService.complete("5005");
}
5.压缩包方式进行流程部署
1.将bpmn文件和png文件压缩成一个zip包
2.通过输入流获取这个zip
3.然后转换成Zip流
4.进行流程部署
//zip部署,流程制作出来要上传服务器 zip文件更便于上传
public static void main(String[] args){
//1.创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.转化出inputStream对象
InputStream is = ActivitiDeployment.class.getClassLoader().getResourceAsStream("diagram/holiday.zip");
//4.将inputStream 转化ZipStream
ZipInputStream zipInputStream = new ZipInputStream(is);
//5.部署
Deployment deployment = repositoryService.createDeployment()
.addZipInputStream(zipInputStream)
.name("请假申请单流程")
.deploy();
//6.输出
System.out.println(deployment.getName());
System.out.println(deployment.getId());
}
6.流程定义的查询
public static void main(String[] args) {
//1.创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.repositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.得到ProcessDefinitionQuery对象,克认为即使一个查询器
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//4.设置条件,查询出当前所有流程定义,流程定义的key=holiday
List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey("holiday")
.orderByProcessDefinitionVersion()//设置根据流程定义版本排序
.desc().list();
//5.输出流程定义信息
for (ProcessDefinition processDefinition : list) {
System.out.println("id"+processDefinition.getId());
System.out.println("key"+processDefinition.getKey());
System.out.println("版本"+processDefinition.getVersion());
System.out.println("名称"+processDefinition.getName());
}
}
7.流程定义的删除
public static void main(String[] args) {
//1.创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.repositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.执行删除流程定义 参数代表流程部署的id
repositoryService.deleteDeployment("1");
}
注意事项:
1.当我们正则执行的其他流程未完全审批结束时,此时如果要删除流程定义信息就会失败
2.如果要强制删除,可以级联删除----流程定义信息要删除的时候,没有跑完的流程信息全部删除repositoryService.deleteDeployment(“1”,true);第二个参数为true代表级联删除这样就会先删除没有完成的流程节点,最后可以删除流程定义信息
8. 流程定义资源查询
通过流程定义对象获取流程定义资源,获取bpmn和png
8.1 需求:
比如用户想查看请假流程具体有哪些步骤要执行
8.2 技术方案:
1.使用activiti的API实现(最简单)
2.其实就是原理层面,可以使用jdbc对blob类型/clob类型数据读取并保存
3.IO流的转换,最后commons-io.jar可以轻松解决IO操作
其中IOUtils工具类是在包common-io.jar里面,要引入依赖:
<!--文件读写 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0</version>
</dependency>
测试类:
public static void main(String[] args) throws Exception {
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RepositoryService对象
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.得到查询器ProcessDefinitionQuery对象
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//4.设置查询条件
processDefinitionQuery.processDefinitionKey("holiday");//参数是流程定义的key
//5.执行查询操作,查询出想要的流程定义
ProcessDefinition processDefinition = processDefinitionQuery.singleResult();
//6.通过流程定义信息,得到部署ID
String deploymentId = processDefinition.getDeploymentId();
//7.通过RepositoryService的方法,实现读取图片信息及bpmn文件信息(I流)
//第一个参数部署id,第二个参数资源名称
InputStream pngIs = repositoryService
.getResourceAsStream(deploymentId,processDefinition.getDiagramResourceName());//png文件名称
InputStream bpmnIs = repositoryService
.getResourceAsStream(deploymentId,processDefinition.getResourceName());//bpmn文件名称
//8.构造出OutputStream流
OutputStream pngOs = new FileOutputStream("D:\\"+processDefinition.getDiagramResourceName());
OutputStream bpmnOs = new FileOutputStream("D:\\"+processDefinition.getResourceName());
//9.输入流,输出流的转换
IOUtils.copy(pngIs,pngOs);
IOUtils.copy(bpmnIs,bpmnOs);
//10.关闭流
pngOs.close();
bpmnOs.close();
pngIs.close();
bpmnIs.close();
}
9.流程历史信息的查询
public static void main(String[] args){
//1.processEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到HistoryService
HistoryService historyService = processEngine.getHistoryService();
//3.得到HistoryActivitiInstanceQuery对象
HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService
.createHistoricActivityInstanceQuery();
//设置流程实例id
historicActivityInstanceQuery.processInstanceId("2501");
//4.执行查询
List<HistoricActivityInstance> list = historicActivityInstanceQuery
.orderByHistoricActivityInstanceStartTime().asc().list();
//5.遍历查询结果
for (HistoricActivityInstance instance:list){
System.out.println(instance.getActivityId());
System.out.println(instance.getActivityName());
System.out.println(instance.getProcessDefinitionId());
System.out.println(instance.getProcessInstanceId());
System.out.println("=====================");
}
}