2、Flowable 详解:概念、作用、场景与 Spring Boot 3 集成指南

【投稿赢 iPhone 17】「我的第一个开源项目」故事征集:用代码换C位出道! 10w+人浏览 1.6k人参与

一、什么是 Flowable?

Flowable 是一个轻量级、高性能、开源的业务流程管理(BPM)和工作流引擎,使用 Java 编写,完全兼容 BPMN 2.0(业务流程建模与标注)、DMN 1.3(决策模型与标注)和 CMMN 1.1(案例管理模型与标注)国际标准。

🔍 起源:
Flowable 最初是 Activiti 项目的分支(2016 年),由原 Activiti 核心团队创建,旨在提供更稳定、更灵活、更现代化的工作流解决方案。


二、Flowable 的核心作用

作用说明
流程定义与执行通过 BPMN 2.0 图形化定义流程,引擎自动执行任务流转
任务管理自动生成待办任务,分配给用户或角色,支持签收、办理、委托等操作
流程实例监控实时跟踪流程状态、历史记录、当前节点、耗时分析
规则决策支持通过 DMN 决策表实现复杂业务规则(如“是否需要风控审核?”)
灵活扩展支持 Java Delegate、Execution Listener、Task Listener 等扩展点
REST API 与 UI提供标准 REST 接口和 Web 管理界面(Modeler、IDM、Task、Admin)

三、典型使用场景

  1. OA 审批系统:请假、报销、采购等多级审批流程
  2. 订单状态机:电商订单从“待支付”到“已完成”的状态流转
  3. IT 工单系统:故障报修、发布审批、权限申请
  4. 金融风控流程:贷款申请、反欺诈审核、人工复核
  5. 内容审核:文章发布、视频审核、多级校对

💡 核心价值:将“流程逻辑”从 Java 代码中剥离,实现 流程可配置、可监控、可追溯,降低系统耦合度。


四、在 Spring Boot 3 项目中集成 Flowable

✅ 环境要求:

  • JDK 17+
  • Spring Boot 3.x(基于 Jakarta EE 9+,包名为 jakarta.*
  • Maven / Gradle
  • 数据库(推荐 PostgreSQL / MySQL)

步骤 1:添加 Maven 依赖

<!-- pom.xml -->
<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Boot Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- Flowable Spring Boot Starter(自动配置引擎) -->
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-spring-boot-starter</artifactId>
        <version>7.2.0</version> <!-- 请使用最新稳定版 -->
    </dependency>

    <!-- 数据库驱动(以 PostgreSQL 为例) -->
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <scope>runtime</scope>
    </dependency>

    <!-- Lombok 工具库 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

⚠️ 注意:
Flowable 6.8+ 已支持 Spring Boot 3 和 Jakarta EE 9+(包名从 javax.* 迁移到 jakarta.*)。


步骤 2:配置 application.yml

# application.yml
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/flowable_demo
    username: flowable
    password: flowable
    driver-class-name: org.postgresql.Driver
  jpa:
    hibernate:
      ddl-auto: validate  # Flowable 会自动建表,此处设为 validate
    show-sql: false

# Flowable 专属配置
# 提前在 IDEA 中安装 Flowable BPMN visualizer 插件,可以让我们在 IDEA 中可视化查看、编辑流程
# Flowable 配置,官方文档 https://www.flowable.com/open-source/docs/bpmn/ch05a-Spring-Boot
flowable:
  # 自动部署流程定义(开发时开启,生产建议关闭)
  check-process-definitions: true
  # 数据库配置(通常与 Spring 共用数据源,无需重复配置)
  database-schema-update: true  # 启动时自动更新表结构(仅开发用!)
  # 异步执行器(用于定时任务、异步任务)
  async-executor-activate: false  # 简单场景可关闭
  # 历史级别:full(记录所有)、audit(默认)、activity、none
  history-level: full

🔒 生产建议

  • database-schema-update: false(禁止自动建表)
  • 通过 Flyway/Liquibase 管理数据库变更

步骤 3:创建流程定义(BPMN 文件)

src/main/resources/processes/ 目录下创建 leave-process.bpmn20.xml

<!-- src/main/resources/processes/leave-process.bpmn20.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:flowable="http://flowable.org/bpmn"
             targetNamespace="http://flowable.org/bpmn">

  <process id="leaveProcess" name="请假审批流程">
    
    <!-- 开始事件 -->
    <startEvent id="startEvent" name="开始"/>
    
    <!-- 提交请假申请(用户任务) -->
    <userTask id="submitLeave" name="提交请假申请" flowable:assignee="${applicant}"/>
    
    <!-- 部门经理审批 -->
    <userTask id="managerApprove" name="部门经理审批" flowable:candidateGroups="managers"/>
    
    <!-- HR 备案 -->
    <userTask id="hrRecord" name="HR 备案" flowable:assignee="hr"/>
    
    <!-- 结束事件 -->
    <endEvent id="endEvent" name="结束"/>
    
    <!-- 连接线 -->
    <sequenceFlow id="flow1" sourceRef="startEvent" targetRef="submitLeave"/>
    <sequenceFlow id="flow2" sourceRef="submitLeave" targetRef="managerApprove"/>
    <sequenceFlow id="flow3" sourceRef="managerApprove" targetRef="hrRecord"/>
    <sequenceFlow id="flow4" sourceRef="hrRecord" targetRef="endEvent"/>
    
  </process>
</definitions>

📝 说明:

  • ${applicant}:流程启动时传入的变量,指定申请人
  • candidateGroups="managers":任务分配给“managers”用户组的所有成员
  • 文件必须放在 resources/processes/ 目录下(默认自动部署路径)

步骤 4:编写 Spring Boot 启动类

// FlowableApplication.java
package com.example.flowable;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Flowable 与 Spring Boot 3 集成的主启动类
 * 启动后,Flowable 会自动:
 * 1. 创建数据库表(如果 database-schema-update=true)
 * 2. 部署 resources/processes/ 下的 BPMN 流程文件
 */
@SpringBootApplication(proxyBeanMethods = false)
public class FlowableApplication {
    public static void main(String[] args) {
        SpringApplication.run(FlowableApplication.class, args);
    }
}

步骤 5:创建流程服务类(核心业务逻辑)

// LeaveWorkflowService.java
package com.example.flowable.service;

import org.flowable.engine.*;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 请假流程服务类
 * 封装 Flowable 引擎的核心操作:启动流程、完成任务、查询任务等
 */
@Service
@RequiredArgsConstructor
public class LeaveWorkflowService {

    // 注入 Flowable 的核心服务组件
    
    // 运行时服务:启动、查询流程实例
    private final RuntimeService runtimeService;
    // 任务服务:查询、办理任务
    private final TaskService taskService;
	// 历史服务:查询已完成的流程和任务
    private final HistoryService historyService;

    /**
     * 启动请假流程
     *
     * @param applicant 申请人用户名(如 "zhangsan")
     * @param days      请假天数
     * @return 流程实例 ID
     */
    @Transactional
    public String startLeaveProcess(String applicant, Integer days) {
        // 准备流程变量(可在 BPMN 中通过 ${variable} 引用)
        Map<String, Object> variables = new HashMap<>();
        variables.put("applicant", applicant); // 指定第一个任务的办理人
        variables.put("days", days);

        // 启动流程:processDefinitionKey 对应 BPMN 文件中 <process id="leaveProcess">
        ProcessInstance processInstance = runtimeService
                .startProcessInstanceByKey("leaveProcess", variables);

        return processInstance.getId();
    }

    /**
     * 查询某用户的待办任务列表
     *
     * @param assignee 用户名
     * @return 任务列表
     */
    public List<Task> getTasksForUser(String assignee) {
        return taskService.createTaskQuery()
                .taskAssignee(assignee)          // 指定办理人
                .orderByTaskCreateTime().desc()  // 按创建时间倒序
                .list();
    }

    /**
     * 完成一个任务(即“办理”任务)
     *
     * @param taskId    任务ID
     * @param variables 任务办理时提交的变量(如审批意见)
     */
    @Transactional
    public void completeTask(String taskId, Map<String, Object> variables) {
        taskService.complete(taskId, variables);
    }

    /**
     * 查询某用户的已办任务(历史任务)
     *
     * @param assignee 用户名
     * @return 历史任务列表
     */
    public List<org.flowable.engine.history.HistoricTaskInstance> getHistoricTasks(String assignee) {
        return historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(assignee)
                .orderByHistoricTaskInstanceEndTime().desc()
                .list();
    }
}

步骤 6:创建 REST Controller(对外提供 API)

// WorkflowController.java
package com.example.flowable.controller;

import com.example.flowable.service.LeaveWorkflowService;
import org.flowable.task.api.Task;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 工作流 REST API 控制器
 * 提供流程启动、任务查询、任务办理等接口
 */
@RestController
@RequestMapping("/workflow")
public class WorkflowController {

    @Resource
    private LeaveWorkflowService workflowService;

    /**
     * 启动请假流程
     * POST /workflow/leave/start
     * 请求体: { "applicant": "zhangsan", "days": 3 }
     */
    @PostMapping("/leave/start")
    public Map<String, String> startLeaveProcess(@RequestBody Map<String, Object> request) {
        String applicant = (String) request.get("applicant");
        Integer days = (Integer) request.get("days");

        String processInstanceId = workflowService.startLeaveProcess(applicant, days);

        Map<String, String> response = new HashMap<>();
        response.put("processInstanceId", processInstanceId);
        response.put("message", "请假流程已启动");
        return response;
    }

    /**
     * 查询用户的待办任务
     * GET /workflow/tasks?assignee=zhangsan
     */
    @GetMapping("/tasks")
    public List<Task> getTasks(@RequestParam String assignee) {
        return workflowService.getTasksForUser(assignee);
    }

    /**
     * 完成任务(办理)
     * POST /workflow/tasks/complete
     * 请求体: { "taskId": "xxx", "approved": true, "comment": "同意" }
     */
    @PostMapping("/tasks/complete")
    public Map<String, String> completeTask(@RequestBody Map<String, Object> request) {
        String taskId = (String) request.get("taskId");
        // 将请求体中的所有字段作为流程变量传递
        workflowService.completeTask(taskId, request);

        Map<String, String> response = new HashMap<>();
        response.put("message", "任务已完成");
        return response;
    }
}

步骤 7:初始化用户与用户组(可选)

Flowable 默认不管理用户,但你可以通过 IdentityService 初始化:

// 初始化用户数据(可在 CommandLineRunner 中执行)
@Component
public class FlowableDataInitializer implements CommandLineRunner {

    @Resource
    private IdentityService identityService;

    @Override
    public void run(String... args) {
        // 创建用户
        if (identityService.createUserQuery().userId("zhangsan").count() == 0) {
            User user = identityService.newUser("zhangsan");
            user.setFirstName("张");
            user.setLastName("三");
            identityService.saveUser(user);
        }

        // 创建用户组
        if (identityService.createGroupQuery().groupId("managers").count() == 0) {
            Group group = identityService.newGroup("managers");
            group.setName("部门经理");
            identityService.saveGroup(group);
        }

        // 将用户加入组
        identityService.createMembership("zhangsan", "managers");
    }
}

五、测试流程

  1. 启动应用

    ./mvnw spring-boot:run
    
  2. 启动流程

    curl -X POST http://localhost:8080/workflow/leave/start \
         -H "Content-Type: application/json" \
         -d '{"applicant":"zhangsan", "days":3}'
    
  3. 查询待办任务

    curl "http://localhost:8080/workflow/tasks?assignee=zhangsan"
    
  4. 完成任务

    curl -X POST http://localhost:8080/workflow/tasks/complete \
         -H "Content-Type: application/json" \
         -d '{"taskId":"<任务ID>", "approved":true, "comment":"同意"}'
    

六、关键注意事项

事项说明
🔐 用户管理Flowable 不包含用户认证系统,需自行集成 Spring Security
🗃️ 数据库初始化首次启动会自动创建 60+ 张表(如 ACT_RU_*, ACT_HI_*
📦 流程部署默认扫描 resources/processes/,也可通过 RepositoryService 动态部署
⏱️ 异步任务复杂逻辑建议使用异步执行器(避免阻塞 HTTP 线程)
📊 历史数据history-level=full 会记录所有变量和表单,注意存储成本

七、扩展建议

  • 集成 Spring Security:实现基于角色的任务权限控制
  • 自定义表单:通过 formKey 关联前端表单页面
  • 监听器扩展:使用 ExecutionListener 在流程节点触发业务逻辑
  • 流程版本管理:通过 RepositoryService 管理多版本流程定义

📚 官方文档

  • Flowable User Guide: https://www.flowable.com/open-source
  • Spring Boot 集成:https://www.flowable.com/open-source/docs/bpmn/ch05a-Spring-Boot
  • Flowable 中文文档

通过以上步骤,你已在 Spring Boot 3 项目中成功集成 Flowable,并实现了一个完整的请假审批流程。如需更复杂场景(如会签、驳回、跳转),可进一步学习 BPMN 高级特性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值