Flowable 工作流引擎实战:从 if-else 状态机到 BPMN 流程编排

SailTrack
2026-05-18
点 赞
0
热 度
0
评 论
0
  1. 首页
  2. 后端开发
  3. Flowable 工作流引擎实战:从 if-else 状态机到 BPMN 流程编排

最近在做 Workforce Hub 的审批模块时,一个需求让我头疼了好几天——请假审批流程。

说白了就是一个"员工提交 → 主管审批 → 人事复核"的流程,听着挺简单的对吧?但架不住产品经理(也就是我自己)要求多:不同假期类型走不同审批链、三天以内免人事复核、超时自动提醒、驳回原因必填……

如果全用 if-else 硬编码状态机,写到后面我估计连自己都看不懂了。

后来硬着头皮引入了 Flowable,踩了不少坑,但也确实解决了问题。今天就来聊聊这个过程。

一、为什么需要工作流引擎?——几个 if-else 引发的惨案

其实一开始我没想用工作流引擎。请假审批嘛,不就是改个状态:

// 我一开始天真的想法
if (leave.getStatus() == PENDING) {
    leave.setStatus(approved ? APPROVED : REJECTED);
    leaveMapper.updateById(leave);
}

这代码跑了一周没问题。直到需求变成了这样:

  • 年假:员工 → 主管 → 人事
  • 事假:员工 → 主管
  • 病假:员工 → 主管 → 人事(附诊断证明)
  • 三天以内:跳过人事复核
  • 主管超过 24 小时未审批 → 自动提醒
  • 驳回后允许重新提交

血泪教训:当审批链开始分叉、节点开始有动态条件时,纯写 if-else 的代码复杂度是指数级增长的。更别提后续还要支持审批历史追溯、流程可视化这些需求。

这时候工作流引擎的价值就体现出来了——它把"流程怎么走"从业务代码里抽离出来,变成可配置的 BPMN 流程图。

二、为什么选 Flowable?——一个不太成熟的选择

市面上 Java 生态的工作流引擎主要有三个:Activiti、Flowable、Camunda。

为了做出选择,我对比了一下:

特性 Activiti 7 Flowable 6.x Camunda 7
Spring Boot 整合 ✅ 原生 ✅ 自动配置 ✅ 社区支持
BPMN 2.0 支持 ✅ 完整 ✅ 完整
文档质量 一般 较好 较好
学习曲线 中等 中等 陡峭
决策表 (DMN)
中文社区 较少 有一些 更少

说实话,选 Flowable 很大程度上是因为它是 Activiti 原班人马出来做的——Activiti 5 的核心团队不满 Alfresco 的方向,出来另起炉灶。而且 Spring Boot 官方有 starter 支持,对咱们这种"能用就行"的学生项目来说最友好。

当然 Camunda 在企业级领域确实更强,但学习曲线太陡了。大三学生搞个课程项目,Flowable 够用了。

我的理解:Flowable 本质上就是把 BPMN 2.0(业务流程建模标注)这个标准规范用 Java 实现了一遍,然后包装成了 Spring Boot 能直接用的组件。

三、流程设计实例——请假审批的 BPMN 之旅

下面是我给 Workforce Hub 设计的请假审批流程:

(流程图)

整个流程分为三步:

第一步:AI 预审。这个比较特别——员工提交请假后,先不直接发给主管,而是过一个 AI 校验节点。比如检查剩余年假天数够不够、有没有重叠的请假记录、病假有没有附诊断证明。不符合规则的直接驳回并告诉原因,不用等主管手动发现。

这个设计思路来自我们项目的核心创新点——“Agent 深度嵌入业务链路”。AI 不只是聊天机器人,它实实在在地参与到了审批流程里。

第二步:部门主管审批。AI 校验通过后,流程到达主管节点。主管可以看到请假详情和 AI 预审结果,然后审批。

第三步:人事复核。如果请假天数超过 3 天,流程自动进入人事复核节点。不到 3 天的直接归档。

审批通过后,自动触发四个服务任务:考勤重算、余额扣减、站内通知、日历同步。

四、Flowable 与 Spring Boot 的整合——到底写了多少代码?

引入 Flowable 其实不复杂,加个依赖就行:

<!-- pom.xml -->
<dependency>
    <groupId>org.flowable</groupId>
    <artifactId>flowable-spring-boot-starter</artifactId>
    <version>6.8.0</version>
</dependency>

启动 Spring Boot 后,Flowable 会自动创建 70+ 张表来管理流程定义、实例、任务、历史记录。小发现:这些表名都以 ACT_ 开头,跟 Activiti 一样的命名约定——毕竟同根同源。

核心代码其实就几个接口:

// 1. 启动一个请假流程
@PostMapping("/leave/submit")
public Result submitLeave(@RequestBody LeaveRequest req) {
    // 构建流程变量
    Map<String, Object> vars = new HashMap<>();
    vars.put("leaveType", req.getLeaveType());
    vars.put("leaveDays", req.getLeaveDays());
    vars.put("applicantId", SecurityUtils.getCurrentUserId());
    
    // 启动流程 - processDefinitionKey 对应 BPMN 文件的 process id
    ProcessInstance pi = runtimeService
        .startProcessInstanceByKey("leave-approval", vars);
    
    return Result.ok(pi.getId());
}

// 2. 查询待办任务
@GetMapping("/tasks/todo")
public Result getTodoTasks() {
    List<Task> tasks = taskService.createTaskQuery()
        .taskAssignee(SecurityUtils.getCurrentUserId())
        .list();
    return Result.ok(tasks);
}

// 3. 审批任务
@PostMapping("/tasks/{taskId}/complete")
public Result completeTask(@PathVariable String taskId, 
                           @RequestBody ApprovalDto dto) {
    Map<String, Object> vars = new HashMap<>();
    vars.put("approved", dto.isApproved());
    vars.put("comment", dto.getComment());
    
    taskService.complete(taskId, vars);
    return Result.ok();
}

踩坑经历:一开始我直接用 taskService.complete() 就完了,没传流程变量——结果下个节点根本不知道这个任务是"通过"还是"驳回",网关判断直接报错。花了一个下午才明白流程变量是 BPMN 里网关判断的依据。

五、AI Agent 怎么嵌入工作流?——这个比较有意思

传统工作流引擎的节点是固定的——用户任务、服务任务、网关。但我们在 Flowable 的基础上做了一个扩展:自定义任务类型——AI 审核节点。

实现方式是在 BPMN 流程里定义一个 Service Task,通过 JavaDelegate 调用 AI Agent:

@Component("aiLeaveChecker")
public class AILeaveCheckerDelegate implements JavaDelegate {
    
    @Override
    public void execute(DelegateExecution execution) {
        // 获取流程变量
        String applicantId = (String) execution.getVariable("applicantId");
        int leaveDays = (int) execution.getVariable("leaveDays");
        String leaveType = (String) execution.getVariable("leaveType");
        
        // 调用 AI Agent 校验规则
        AILeaveCheckResult result = aiAgentService.checkLeaveRules(
            applicantId, leaveType, leaveDays);
        
        // 将校验结果写入流程变量,供网关判断
        execution.setVariable("aiCheckPassed", result.isPassed());
        execution.setVariable("aiCheckReason", result.getReason());
    }
}

然后在 BPMN 里这样引用:

<serviceTask id="aiCheck" name="AI预审" 
    flowable:delegateExpression="${aiLeaveChecker}"/>

网关会根据 aiCheckPassed 变量自动路由到"主管审批"或"驳回"分支——全程不需要写 if-else。

说实话,这个设计一开始我心里也没底——把 AI 的判断直接作为流程的路由依据,万一 AI 判断错了呢?后来加了一个兜底:AI 校验不通过的情况下,员工可以走"人工申诉"通道,绕过 AI 节点直接到主管。

六、流程可视化——调试利器

Flowable 自带了一个流程设计器和监控面板,开发阶段可以直接看到流程跑到哪了:

http://localhost:8080/flowable-ui

当然生产环境一般不会开这个面板。我们项目里自己画了一个轻量的流程跟踪页面,让用户能看到自己提交的请假当前在哪个环节、谁在审批、预计多久能完成。

总结

我的收获

  1. 工作流引擎的核心价值是"流程与代码解耦"——不是让代码变少,而是让流程变可维护
  2. Flowable 学习曲线有,但不高——看懂 BPMN 2.0 的基本元素(开始/结束/任务/网关/连线)就够用了
  3. AI + 工作流是个有意思的组合——Agent 从"工具"变成了"流程参与者"

给初学者的建议:别一上来就想着画特别复杂的流程图。先从一个"开始 → 一人审批 → 结束"的极简流程开始,跑通了再加网关、加服务任务。

下一步:审批流程做完后,下一步就是把 AI 知识库接进来——员工在申请请假时可以直接 @AI 问"我还有几天年假",这个后面单独写一篇。


技术栈:Java 17 + Spring Boot 3.x + Flowable 6.8 + MyBatis-Plus + MySQL 8.4
环境信息:macOS + IntelliJ IDEA + Docker Compose(本机开发)
更新日期:2026年5月


让我们忠于理想,让我们面对显示

SailTrack

entp 辩论家

站长

不具版权性
不具时效性

文章内容不具时效性。若文章内容有错误之处,请您批评指正。

目录

欢迎来到SailTrack的站点,为您导航全站动态

32 文章数
11 分类数
3 评论数
28标签数