别再手动循环了!Flowable多实例任务实战:用Spring Boot + MySQL搞定批量审批流

Flowable多实例任务Spring Boot审批流程
于 2026-05-29 11:24:37 修改
·本内容遵循CC 4.0 BY-SA版权协议

告别循环代码:Flowable多实例任务在Spring Boot中的高效实践

当你在处理"部门全员会签"或"多领导并行审批"这类需求时,是否还在用for循环逐个创建审批任务?上周我接手了一个采购审批系统改造项目,原代码中密密麻麻的循环和状态判断让我意识到——是时候引入Flowable的多实例特性了。本文将带你用Spring Boot和MySQL实现一个真实的批量审批流程,彻底摆脱手动循环的繁琐。

1. 为什么选择多实例替代循环逻辑

去年我们团队重构了一个存在三年的报销审批系统,原系统用传统循环处理部门会签,代码中充斥着for循环和if-else判断。当需要增加"超过半数同意即通过"的业务规则时,开发人员不得不修改多处状态判断逻辑。而采用Flowable多实例后,同样的需求只需在BPMN配置中添加一行completionCondition表达式。

多实例任务与传统循环对比:

特性 手动循环实现 Flowable多实例
审批进度可视化 需额外开发状态跟踪逻辑 内置nrOfCompletedInstances变量
动态调整参与者 修改代码重新部署 调整collection变量实时生效
审批规则变更 需重写判断逻辑 修改BPMN配置无需停机
历史记录完整性 需手动记录每个实例 引擎自动维护执行轨迹

在采购审批场景中,多实例尤其适合以下情况:

  • 并行会签:需要多个部门同时审批采购申请
  • 动态参与者:审批人列表来自运行时变量(如根据采购类型决定)
  • 灵活完成条件:如"3人中有2人同意即可通过"
JAVA
// 传统循环实现示例(问题明显)
public void createApprovalTasks(List<String> auditors) {
for (String auditor : auditors) {
Task task = new Task();
task.setAssignee(auditor);
task.setStatus("PENDING");
// 需要手动维护任务关系...
taskRepository.save(task);
}
}

2. Spring Boot环境快速集成

从零开始搭建一个支持多实例的运行环境比想象中简单。我习惯用MySQL作为流程数据存储,它的事务特性对流程一致性很重要。以下是关键依赖:

XML
<dependencies>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>6.7.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>

application.yml中配置数据库和异步执行器(多实例并行审批的关键):

YAML
flowable:
async-executor-activate: true
database-schema-update: true
history-level: audit
spring:
datasource:
url: jdbc:mysql://localhost:3306/flowable_db?useSSL=false
username: root
password: 123456

注意:生产环境务必开启async-executor-activate,这是并行多实例能真正并发执行的核心配置。曾有个项目因为漏配这项,导致"并行"审批变成了队列等待。

3. 采购审批多实例实战

假设我们要实现这样一个场景:采购申请超过5万元时需要财务部、法务部、技术部三个部门并行会签,任意两个部门同意即可通过。以下是完整的实现步骤。

3.1 定义多实例BPMN模型

resources/processes目录下创建purchase_approval.bpmn

XML
<process id="purchase_approval" name="采购审批流程">
<startEvent id="start"/>
<userTask id="department_approval" name="部门会签">
<multiInstanceLoopCharacteristics
isSequential="false"
flowable:collection="${approvalDepartments}"
flowable:elementVariable="department">
<completionCondition>
${nrOfCompletedInstances >= 2}
</completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>
<sequenceFlow sourceRef="department_approval" targetRef="end"/>
<endEvent id="end"/>
</process>

关键配置解析:

  • isSequential="false":开启并行模式
  • collection:使用动态部门列表变量
  • completionCondition:自定义完成条件

3.2 实现动态参与者逻辑

在服务层注入运行时变量。这里演示从数据库获取审批部门:

JAVA
@Service
public class PurchaseApprovalService {
@Autowired
private RuntimeService runtimeService;
public void startApprovalProcess(Long purchaseId) {
Map<String, Object> variables = new HashMap<>();
variables.put("approvalDepartments", getApprovalDepartments(purchaseId));
runtimeService.startProcessInstanceByKey(
"purchase_approval",
purchaseId.toString(),
variables
);
}
private List<String> getApprovalDepartments(Long purchaseId) {
Purchase purchase = purchaseRepository.findById(purchaseId);
if (purchase.getAmount() > 50000) {
return Arrays.asList("finance", "legal", "tech");
}
return Collections.singletonList("finance");
}
}

3.3 处理多实例任务

创建Controller处理审批操作:

JAVA
@RestController
@RequestMapping("/approval")
public class ApprovalController {
 
@PostMapping("/complete/{taskId}")
public String completeTask(@PathVariable String taskId,
@RequestParam boolean approved) {
Task task = taskService.createTaskQuery()
.taskId(taskId)
.singleResult();
Map<String, Object> variables = new HashMap<>();
variables.put("approved_" + task.getVariable("department"), approved);
taskService.complete(taskId, variables);
return "审批提交成功";
}
}

实用技巧:在变量名前加上部门前缀(如approved_finance),方便在网关判断时区分不同部门的审批结果。

4. 多实例开发中的避坑指南

在三个实际项目中使用多实例后,我总结了这些容易踩坑的场景:

4.1 变量作用域问题

多实例任务中的变量分为两种:

  • 实例级变量:通过elementVariable定义,每个实例独立
  • 流程级变量:通过runtimeService.setVariable设置,全局可见

常见错误是在子实例中误改流程变量。正确做法:

JAVA
// 错误示范:直接修改流程变量
taskService.setVariable(taskId, "approvalResult", result);
 
// 正确做法:使用局部变量
taskService.setVariableLocal(taskId, "departmentResult", result);

4.2 事务边界控制

当多实例任务与业务操作混合时,注意事务划分:

JAVA
@Transactional
public void approvePurchase(String taskId, ApprovalDTO dto) {
// 1. 先完成Flowable任务
taskService.complete(taskId, dto.getVars());
// 2. 再更新业务状态(与任务在同一个事务中)
purchaseService.updateStatus(dto.getPurchaseId());
}

4.3 性能优化建议

处理大规模并行审批时(如超过50个实例):

  1. 调整flowable.async-executor.core-pool-size(默认8)
  2. 避免在collection表达式中执行耗时查询
  3. 对固定参与者列表使用缓存

5. 进阶:动态调整运行中的多实例

上周遇到个需求:采购申请金额变更后,需要动态增减审批部门。通过API可以实时修改运行中的多实例��

JAVA
public void adjustApprovers(String processInstanceId, List<String> newDepartments) {
Execution execution = runtimeService.createExecutionQuery()
.processInstanceId(processInstanceId)
.activityId("department_approval")
.singleResult();
runtimeService.setVariable(
processInstanceId,
"approvalDepartments",
newDepartments
);
runtimeService.addMultiInstanceExecution(
"department_approval",
execution.getId(),
null
);
}

这个方案比重新发起流程更符合业务实际,但要注意:

  • 新增的实例会立即开始并行执行
  • 已完成的实例不受影响
  • 总实例数变化会自动更新nrOfInstances
Spring Boot整合流程引擎Flowable
本文系统介绍Spring Boot整合流程引擎Flowable的完整实践路径,涵盖工作流核心概念、BPMN 2.0协议规范及其建模要素、Flowable与Activiti的演进关系,并重点展开本地Flowable UI部署、Spring Boot项目搭建、流程定义与启动代码实现、动态变量绑定(如assignee、UEL表达式)及Flowable内置数据库表结构说明,聚焦企业级流程自动化开发关键环节。
孤居自傲
12932
别再手动搭后台了用这个若依Plus脚手架,5分钟集成Flowable工作流和MybatisPlus
本文介绍若依Plus增强型脚手架,支持5分钟快速搭建企业级后台系统,深度集成了Flowable工作流引擎和MyBatisPlus持久层框架。涵盖环境准备、关键配置、流程设计器增强(如会签/回退/表单绑定)、多租户隔离、数据权限控制及性能优化等核心技术点,显著提升审批类系统的开发交付效率。
不懂就承认
258
基于RuoYi-Vue+Spring Boot的OA系统源码,内置Flowable流程引擎,支持可视化配置与多级审批
237
doc_wei/erp-pro50+电子流程一站式解决方案
doc_wei/erp-pro是一款基于Spring Boot的低代码开发平台,提供超过50种电子流程的一站式解决方案。涵盖行政办公、资产管理、CRM、项目管理等七大类流程,并支持可视化流程设计、多实例任务处理、动态审批配置等功能。该平台采用Flowable工作流引擎,具有高性能架构和灵活可配置特点,适用于企业数字化转型。
殷巧或
791
全栈编程基础知识2
本文系统梳理Java全栈开发中的关键底层机制与实践要点,涵盖集合框架(ArrayList/LinkedList)、HashMap底层实现(JDK1.7/1.8差异)、线程安全方案(synchronized/Lock/ConcurrentHashMap/ThreadLocal)、MySQL索引失效场景、Spring Boot自动配置原理、@Transactional失效原因、Git merge/rebase语义区别、防重复提交策略(分布式锁/幂等性)、主流流程引擎(Activiti/Flowable)及典型分布式挑战(事务一致性、链路追踪)。重点突出后端工程化必备技术深度。
不懂代码的孩子
55
SpringBoot程序启动时执行初始化代码(示例代码)
该博客介绍了如何在Spring Boot应用启动时监听上下文刷新事件,并实现一个死循环来监控Redis缓存。当缓存时间到达时,程序自动清理指定key的缓存条目。主要涉及Spring ApplicationListener接口、RedisUtils工具类和数据清理逻辑。
nezhaxiaopengyou
332
大学cs学习路线(主要java后端,包含前端、产品经理)
没必要太早学,我做项目的时候也没用到。
知兀
1106
AI 编程时代,为什么脚手架依然不可替代?
本文探讨AI编程兴起背景下脚手架不可替代的原因,指出AI生成代码存在安全漏洞、架构失配、可维护性差、缺乏多租户支持等核心问题。Scaffold通过四层严格分层架构(Controller/Service/Repository/Domain)、框架级安全兜底、20+模块化企业组件、智能依赖解析及内置AI文档体系,为AI提供结构化协作环境,实现全栈交付与规范约束,成为AI编码的‘方向盘与刹车’。
YaYicho
340
enterprise-flowable:工作流,包含单人审批、多人审批、流程分支、指定退回、流程图展示
**Spring-Boot集成**: Spring-Boot简化了Spring应用的初始化和配置,使得开发流程更加高效。
ywnwx
9684
Flowable深入浅出-12 Flowable-BPMN操作流程之用户任务UserTask
该项目基于Spring Boot,集成了MyBatis、MySQLFlowable流程引擎,包含常用的开
书山登峰人
6906
如何使用Spring Boot结合Flowable实现轻量级审批流程?
本文介绍了如何使用Spring Boot框架实现一个简单的审批流程。首先,通过Activiti或Flowable框架定义流程模型、任务和用户。然后,利用Spring Boot的Web组件、数据访问技术、异步处理、消息队列、定时任务等功能实现审批流程的各个环节。最后,通过Spring Security控制访问权限,并使用日志框架和管理工具进行监控。
chenxi_98
spring-cloud 集成 flowable 工作流
```yamlflowable: db: type: mysql url: jdbc:mysql://localhost:3306/flowable?
孤狼heng小布
6396
Flowable深入浅出-13 Flowable-BPMN操作流程之流程进展查看之流程图
本文介绍了一个名为flowablestudy的Maven项目,采用Spring Boot框架并集成了MyBatis、MySQLFlowable流程引擎。项目包含常用开发依赖,适用于企业级应用开发。
书山登峰人
6548
Flowable深入浅出-15 Flowable-BPMN操作流程之排他网关
本文介绍了一个名为flowablestudy的Maven项目,采用Spring Boot框架并集成了MyBatis、MySQLFlowable流程引擎。该项目包含常用开发依赖,适用于企业级应用开发。
书山登峰人
3832
流程引擎(Flowable+Activiti)
整合流程引擎在实际应用中,Flowable和Activiti可以作为服务组件,通过API与前端应用(如Spring Boot应用)进行交互。
冰 河
4589
多实例任务实战指南基于Flowable实现会签与并行审批的5步解决方案
SW_孙维
Flowable 6.7.2 + Spring Boot实战:5分钟搞定请假审批流程开发
三言两个菜