我们今天分享activiti 集成 springBoot 配置入门使用,入门是关键 也是我们成为大牛的必经之路,废话少说,上:
一、配置启动初始化
1、pom文件引入
org.springframework.boot spring-boot-starter-web org.activiti activiti-spring-boot-starter 7.1.0.M6 mysql mysql-connector-java
2、数据库配置
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driver #mysql 8.XX版本额驱动url: jdbc:mysql://16.2.8.1:3306/activiti?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&nullCatalogMeansCurrent=trueusername: rootpassword: 't6n?_'activiti:check-process-definitions: true #自动检查、部署流程定义文件#1.flase:默认值。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常#2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建#3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)#4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)database-schema-update: true#activiti7默认不生成历史信息表,开启历史表db-history-used: true#记录历史等级 可配置的历史级别有none, activity, audit, full#none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。#activity:级别高于none,保存流程实例与流程行为,其他数据不保存。#audit:除activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。#full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。history-level: full
注意:如果配置的是8以上版本驱动,而你的数据库是5.7 ,你需要在数据库连接后面加上:
&nullCatalogMeansCurrent=true
如果不加可能报错:
Cause: java.sql.SQLSyntaxErrorException: Table ‘myactiviti.act_ge_property‘ doesn‘t exist
原因:
因为mysql使用schema标识库名而不是catalog,因此mysql会扫描所有的库来找表,如果其他库中有相同名称的表,activiti就以为找到了,本质上这个表在当前数据库中并不存在。
设置nullCatalogMeansCurrent=true,表示mysql默认当前数据库操作,在mysql-connector-java 5版本该参数默认为true,6版本以上默认为false,因此8版本驱动需要设置nullCatalogMeansCurrent=true。
3、bpmn 文件生成
先简单参考,此处仅贴出业务工作流图:

4、服务启动初始化脚本25张表
@SpringBootApplication
public class ActivitiApplication {public static void main(String[] args) {SpringApplication.run(ActivitiApplication.class,args);}
}
结果如下图:

服务启动后验证下面流程!
二、测试验证流程
1、 启动工作流
@Testpublic void testStart(){ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myTestAct");System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());System.out.println("流程实例id:" + processInstance.getId());System.out.println("当前活动Id:" + processInstance.getActivityId());}
执行结果打印日志:
流程定义id:myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
流程实例id:79156f70-c319-11ed-9c09-9a473ddfa0cf
当前活动Id:null
2、查询当前人待执行的任务
@Testpublic void testFindPersonalTasks() {
// 任务负责人String assignee = "appler";// String assignee = "leader";
// 根据流程key 和 任务负责人 查询任务List list = taskService.createTaskQuery().processDefinitionKey("myTestAct") //流程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());}}
查询结果日志:
流程实例id:79156f70-c319-11ed-9c09-9a473ddfa0cf
任务id:791a5174-c319-11ed-9c09-9a473ddfa0cf
任务负责人:appler
任务名称:请假申请
注意:工作流启动后,首先只有appler下会有任务(如上),如果此时你查leader、hrbp 下面是没有任务的;只有appler下的任务执行完成之后,流程才进入到leader下面;同理leader下的任务执行之后,会流到hrbp下面,这就是工作流的精髓所在!
3、提交完成任务
@Testpublic void testCompletTask(){/*** 根据流程key 和 任务的负责人 查询任务* 返回一个任务对象*/Task task = taskService.createTaskQuery().processDefinitionKey("myTestAct") //流程Key.taskAssignee("appler") //要查询的负责人.singleResult();System.out.println("流程实例id:" + task.getProcessInstanceId());System.out.println("任务id:" + task.getId());System.out.println("任务负责人:" + task.getAssignee());System.out.println("任务名称:" + task.getName());taskService.complete(task.getId());//提交完成任务,参数:任务id}
执行后日志
流程实例id:79156f70-c319-11ed-9c09-9a473ddfa0cf
任务id:791a5174-c319-11ed-9c09-9a473ddfa0cf
任务负责人:appler
任务名称:请假申请
注意:此时appler 提交执行完了,就可以查询并提交leader下面的任务了!
4、查询出当前所有的流程定义
@Testpublic void testQueryDefinition(){//得到ProcessDefinitionQuery 对象ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();//条件:processDefinitionKey =myTestActList definitionList = processDefinitionQuery.processDefinitionKey("myTestAct").orderByProcessDefinitionVersion()//orderByProcessDefinitionVersion 按照版本排序.desc()//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());}}
结果日志
流程定义 id=myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
流程定义 name=员工请假审批流程
流程定义 key=myTestAct
流程定义 Version=1
流程部署ID =f40d7fb6-c318-11ed-bd79-9a473ddfa0cf
此时只有一个流程正在执行,正常情况在可能有多个流程同时执行!
5、查询某个流程实例状态
@Testpublic void testQueryProcess() {String processDefinitionKey = "myTestAct";List list = runtimeService.createProcessInstanceQuery().processDefinitionKey(processDefinitionKey)//.list();for (ProcessInstance processInstance : list) {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());}}
结果日志
流程实例id:79156f70-c319-11ed-9c09-9a473ddfa0cf
所属流程定义id:myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
是否执行完成:false
是否暂停:false
当前活动标识:null
业务关键字:null
6、删除某个流程记录
@Testpublic void testDeleteDeployment() {// 流程部署idString deploymentId = "70302f48-c2f7-11ed-9448-9a473ddfa0cf";//删除流程定义,如果该流程定义已有流程实例启动则删除时出错repositoryService.deleteDeployment(deploymentId);//设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式,如果流程//repositoryService.deleteDeployment(deploymentId, true);}
对应 act_re_deployment 张表里的数据,可以查询看看。
7、查看历史信息(已经结束的流程)
@Testpublic void testFindHistory(){//获取 actinst表的查询对象HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();//查询 actinst表,条件:根据 InstanceId 查询,查询一个流程的所有历史信息instanceQuery.processInstanceId("79156f70-c319-11ed-9c09-9a473ddfa0cf");// .activityType("serviceTask")instanceQuery.finished();//查询 actinst表,条件:根据 DefinitionId 查询,查询一种流程的所有历史信息//增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序instanceQuery.orderByHistoricActivityInstanceStartTime().asc();//查询所有内容List 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());}}
结果日志
_2
StartEvent
myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
79156f70-c319-11ed-9c09-9a473ddfa0cf
_3
请假申请
myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
79156f70-c319-11ed-9c09-9a473ddfa0cf
_4
总监审批
myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
79156f70-c319-11ed-9c09-9a473ddfa0cf
_5
人事审批
myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
79156f70-c319-11ed-9c09-9a473ddfa0cf
_6
EndEvent
myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
79156f70-c319-11ed-9c09-9a473ddfa0cf
到此、初级操作分享完成,后期我们分享其高级功能,敬请期待!