SpringBoot整合Activiti7工作流引擎
在Idea中安装bpnm可视化插件
引入activiti依赖
<!-- 引入Activiti7 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.0.0.Beta3</version>
<!-- 排除掉activiti中的mybatis,否则项目启动会报错 -->
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>
</dependency>
这是我没排除时的项目启动报错
配置文件
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatisplus
username: root
password: 123456
# 初始化大小
initial-size: 5
# 最小连接数
min-idle: 5
# 最大连接数
max-active: 20
# 获取连接等待超时的时间
max-wait: 5000
# 打开PSCache,并且指定每个连接上PSCache的大小
pool-prepared-statements: true
# asyncInit是1.1.4中新增加的配置,如果有initialSize数量较多时,打开会加快应用启动时间
async-init: true
# 配置监控统计拦截的filters
filters: stat,config
# druid监控配置信息
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
type: com.alibaba.druid.pool.DruidDataSource
devtools:
restart:
enabled: true #设置开启热部署
additional-paths: src/main/java #重启目录
#activiti配置
activiti:
#1.flase:默认值。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
#2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
#3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
#4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
database-schema-update: true
# 自动部署验证设置:true-开启(默认)、false-关闭 true时项目启动会自动部署
check-process-definitions: false
# 注意,如果activiti后面加上了/,就要求启动的时候process文件夹中需要有流程定义文件
# 是指定activiti流程描述文件的前缀(路径),启动时,activiti就会去寻找此路径下的流程描述文件,并且自动部署
process-definition-location-prefix: classpath:/processes/
# suffix 是一个String数组,表示描述文件的默认后缀名,默认**.bpmn和**.bpmn20.xml
# process-definition-location-suffixes:
# - **.bpmn
# - **.bpmn20.xml
# Activiti7历史数据无法自动插入,开启下面两个配置
# 检测历史表是否存在 activiti7默认没有开启数据库历史记录 启动数据库历史记录
db-history-used: true
# 保存历史数据
#记录历史等级 可配置的历史级别有none, activity, audit, full
#none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。
#activity:级别高于none,保存流程实例与流程行为,其他数据不保存。
#audit:除activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。
#full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。
history-level: audit
# 关闭自动部署
deployment-mode: never-fail
# 解决频繁查询SQL问题
async-executor-activate: false
启动项目
项目启动后会自动初始化activiti相关表
activiti会创建一共有25张表
activiti数据表介绍
绘制流程图
- 新建*.bpmn20.xml 文件:New -> New Activity 6.x BPMN 2.x file
- 在文件上右键选择
view BPMN(Activity ) Diagram
- 绘制流程图
流程部署
自动部署
当check-process-definitions: true
配置为true时则为自动部署
需要把流程文件放到/processes/文件夹下
手动部署
编写部署测试类
/*
手动部署流程
*/
@Test
public void deployment(){
DeploymentBuilder deployment = repositoryService.createDeployment();
Deployment 请假流程 = deployment.name("请假流程")
.addClasspathResource("processes/leave.bpmn20.xml")
.addClasspathResource("processes/leave.png")
.deploy();
System.out.println("部署ID:"+请假流程.getId());
System.out.println("部署名称:"+请假流程.getName());
}
/**
* 查询流程部署列表
*/
@Test
public void listDeployments() {
List<Deployment> deployments = this.repositoryService.createDeploymentQuery().list();
if (!deployments.isEmpty()) {
deployments.forEach(deployment -> {
System.out.println("Id:" + deployment.getId());
System.out.println("Name:" + deployment.getName());
System.out.println("DeploymentTime:" + deployment.getDeploymentTime());
System.out.println("Key:" + deployment.getKey());
});
}
}
/**
* 删除流程部署
*/
@Test
public void deleteDeplyoment(){
//第二个参数为级联删除,默认为false(有该流程的实例则不能删除),设置true则为级联删除
repositoryService.deleteDeployment("8441e980-a5bc-11ed-a133-00e04c362f39",false);
}
部署成功后表数据
部署表:act_re_deployment
流程定义表:act_re_procdef
流程实例
流程定义(ProcessDefinition)与流程实例(ProcessInstance)是一对多关系
/**
* 启动一个流程实例
*/
@Test
public void startProcess(){
String processDefinitionKey = "leave";
String businessKey = "123";
HashMap<String,Object> map = new HashMap<>();
map.put("student","liliyun");
// ProcessInstance leave = runtimeService.startProcessInstanceByKey("leave");
ProcessInstance leave = runtimeService.startProcessInstanceByKey(processDefinitionKey,businessKey, map);
System.out.println("businessKey:"+leave.getBusinessKey());
System.out.println("name:"+leave.getName());
System.out.println("id:"+leave.getId());
System.out.println("DeploymentId:"+leave.getDeploymentId());
System.out.println("ProcessDefinitionId:"+leave.getProcessDefinitionId());
Date startTime = leave.getStartTime();
System.out.println("StartTime:"+ startTime);
System.out.println("流程实例id:"+leave.getProcessInstanceId());
}
/**
* 查询流程实例
*/
@Test
void findInstance(){
List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey("123").list();
list.forEach(processInstance -> {
System.out.println("实例id:"+processInstance.getProcessInstanceId());
System.out.println("实例name:"+processInstance.getName());
System.out.println("实例起始用户:"+processInstance.getStartUserId());
});
}
/**
* 挂起流程实例
*/
@Test
public void suspendProcessInstance() {
String processInstanceId = "354709ac-477f-11ed-abfa-e4a8dfd43d4a";
this.runtimeService.suspendProcessInstanceById(processInstanceId);
}
/**
* 激活流程实例
*/
@Test
public void activeProcessInstance() {
String processInstanceId = "354709ac-477f-11ed-abfa-e4a8dfd43d4a";
this.runtimeService.activateProcessInstanceById(processInstanceId);
}
/**
* 删除流程实例
*/
@Test
public void deleteProcessInstance() {
String processInstanceId = "354709ac-477f-11ed-abfa-e4a8dfd43d4a";
String reason = "测试删除流程实例";
this.runtimeService.deleteProcessInstance(processInstanceId, reason);
}
任务管理
/**
* 查询任务列表
*/
@Test
List<Task> findTask(){
TaskQuery taskQuery = taskService.createTaskQuery();
List<Task> list = taskQuery
.processDefinitionKey("leave")//流程实例key
// .taskAssignee("程长新")//任务负责人
.list();
list.stream().forEach(task -> {
System.out.println("任务id:"+task.getId());
System.out.println("任务名称:"+task.getName());
System.out.println("任务负责人:"+task.getAssignee());
System.out.println("流程定义id:"+task.getProcessDefinitionId());
System.out.println("流程实例id:"+task.getProcessInstanceId());
System.out.println("任务创建时间:"+task.getCreateTime());
System.out.println(task.isSuspended());
});
return list;
}
/**
* 处理任务
*/
@Test
void dealTask(){
List<Task> taskList = findTask();
for (Task task : taskList) {
//处理负责人为程长新的任务
if ("程长新".equals(task.getAssignee())){
taskService.complete(task.getId());
System.out.println("处理任务id:"+task.getId());
}
}
}
/**
* 拾取任务
*/
@Test
public void claimTask() {
String taskId = "16beabc1-479f-11ed-9c3a-e4a8dfd43d4a";
String userId = "jason";
Task task = this.taskService.createTaskQuery().taskId(taskId).singleResult();
taskService.claim(taskId, userId);
}
/**
* 归还任务
*/
@Test
public void returnTask() {
String taskId = "16beabc1-479f-11ed-9c3a-e4a8dfd43d4a";
Task task = this.taskService.createTaskQuery().taskId(taskId).singleResult();
// 归还任务
taskService.unclaim(taskId);
}
/**
* 交办任务
*/
@Test
public void handoverTask() {
String taskId = "16beabc1-479f-11ed-9c3a-e4a8dfd43d4a";
String userId = "jack";
Task task = this.taskService.createTaskQuery().taskId(taskId).singleResult();
// 交办任务
taskService.setAssignee(taskId, userId);
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤