SpringBoot集成Flowable工作流引擎与bpmn-js可视化设计器实战
在OA、ERP、CRM等企业级应用开发中工作流引擎是处理复杂业务流程自动化的核心组件。手动编写BPMN 2.0规范的XML文件不仅繁琐易错而且难以直观地设计和调整流程。因此一个可视化的流程设计器成为提升开发效率的关键。本文将聚焦于如何在SpringBoot项目中集成工作流引擎并引入强大的前端流程编辑器bpmn-js构建一个从流程设计、部署到执行的全栈解决方案。通过本篇教程你将掌握从零开始搭建一个具备可视化流程设计能力的工作流应用的核心步骤无论是用于毕业设计、内部系统升级还是技术学习都能获得一套可直接复用的代码框架。1. 工作流引擎与可视化编辑器核心概念在开始实战之前我们需要明确几个核心概念这有助于理解整个技术栈的定位和协作关系。工作流引擎是一个软件组件它负责执行业务流程的自动化。它根据预定义的流程模型通常用BPMN标准描述来驱动任务的流转例如决定下一个处理人、发送通知、调用服务等。在Java生态中Activiti和Flowable是两个非常流行且同源的开源工作流引擎。它们都基于BPMN 2.0标准提供了完整的流程定义、部署、运行和历史查询API。简单来说工作流引擎是后端的“大脑”它解析流程定义管理流程实例的状态和生命周期。BPMN 2.0是业务流程模型与符号的行业标准。它定义了一套图形元素如任务、网关、事件和对应的XML模式用于精确描述业务流程。一个BPMN文件.bpmn或.bpmn20.xml本质上就是一个符合特定规范的XML文档它描述了流程的步骤、顺序和决策逻辑。工作流引擎正是读取并执行这个XML文件。bpmn-js是一个基于JavaScript的BPMN 2.0流程图查看与编辑库。它提供了我们在网页上看到的那个可视化的流程设计器界面允许用户通过拖拽的方式绘制流程图。其核心价值在于它能够将用户绘制的图形实时转换为标准的BPMN 2.0 XML也能将已有的BPMN XML渲染成可视化图形。在我们的架构中bpmn-js作为前端编辑器负责生成或修改流程定义文件BPMN XML而后端的工作流引擎则负责执行这个文件。技术栈协作关系可以这样理解开发者或业务人员在前端bpmn-js绘制流程图 - 生成BPMN XML- 通过HTTP接口发送到后端SpringBoot应用- 后端调用工作流引擎如Flowable的API部署该XML - 引擎将其解析并持久化到数据库 - 业务系统通过调用引擎的RuntimeService、TaskService等API来启动流程、完成任务、查询进度。2. 环境准备与项目初始化我们将创建一个标准的SpringBoot项目并集成Flowable工作流引擎。为了清晰演示我们使用一个简单的“请假流程”作为业务场景。2.1 技术栈与版本说明后端框架: Spring Boot 2.7.x (选择LTS版本如2.7.18)工作流引擎: Flowable Spring Boot Starter 6.7.0 (建议使用较新稳定版)前端库: bpmn-js 8.x 或 9.x数据库: MySQL 5.7 或 8.0构建工具: Maven 3.6JDK: 1.8 或 11IDE: IntelliJ IDEA 或 Eclipse注意版本兼容性很重要。Spring Boot 2.7.x 与 Flowable 6.x 可以良好集成。如果遇到启动问题请检查依赖的版本号是否冲突。2.2 创建SpringBoot项目使用Spring Initializr (https://start.spring.io) 或IDE的创建向导生成一个基础项目。需要选择的依赖包括Spring Web: 提供RESTful API支持。Spring Data JPA(可选) 或MyBatis-Plus: 用于业务数据持久化。本例为简化主要使用Flowable自动管理的表。MySQL Driver: 数据库连接。2.3 添加核心Maven依赖在项目的pom.xml文件中添加Flowable和数据库等核心依赖。除了Initializr生成的依赖我们需要手动加入flowable-spring-boot-starter。?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.7.18/version !-- 使用稳定的LTS版本 -- relativePath/ /parent groupIdcom.example/groupId artifactIdspringboot-flowable-demo/artifactId version0.0.1-SNAPSHOT/version namespringboot-flowable-demo/name descriptionDemo project for Spring Boot with Flowable and BPMN.js/description properties java.version1.8/java.version flowable.version6.7.0/flowable.version /properties dependencies !-- Spring Boot Web -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Flowable Spring Boot Starter -- dependency groupIdorg.flowable/groupId artifactIdflowable-spring-boot-starter/artifactId version${flowable.version}/version /dependency !-- 数据库相关 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency !-- 常用工具 -- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId configuration excludes exclude groupIdorg.projectlombok/groupId artifactIdlombok/artifactId /exclude /excludes /configuration /plugin /plugins /build /project关键依赖解释flowable-spring-boot-starter: 这是集成Flowable的核心。它会自动配置Flowable的各个服务如RuntimeService,TaskService并注入Spring容器同时自动创建所需的数据库表。spring-boot-starter-data-jpa: 方便进行业务数据操作。Flowable引擎本身会使用配置的数据源来创建和管理自己的表。版本管理在properties中统一管理flowable.version便于升级和维护。2.4 配置数据库连接在application.yml或application.properties中配置数据库连接信息。Flowable启动时会自动检查并创建约60张表数量因版本和配置而异建议为工作流引擎使用独立的数据库或schema。# application.yml spring: datasource: url: jdbc:mysql://localhost:3306/flowable_demo?useUnicodetruecharacterEncodingutf-8useSSLfalseserverTimezoneAsia/Shanghai username: root password: yourpassword driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update # 对于业务表JPA可以自动更新。Flowable表由其自身管理。 show-sql: true properties: hibernate: dialect: org.hibernate.dialect.MySQL5InnoDBDialect # Flowable 特定配置 (可选有默认值) flowable: # 是否在启动时自动部署 classpath:/processes/ 下的流程定义文件 async-executor-activate: false # 关闭历史数据记录级别可选值none, activity, audit, full history-level: audit配置要点spring.datasource: Flowable依赖此数据源创建和管理其所有运行时数据表、历史表、身份表等。flowable.async-executor-activate: 异步执行器用于定时任务等在简单演示中可以关闭。flowable.history-level: 历史记录级别。audit是常用级别会保存流程实例、任务、变量等审计信息。full会保存所有细节包括变量更新数据量最大。启动SpringBoot应用如果控制台没有报错并且看到类似“creating 60 new tables”的日志说明Flowable自动建表成功数据库中将出现ACT_RE_*(资源表)、ACT_RU_*(运行时表)、ACT_HI_*(历史表)、ACT_ID_*(身份表) 等系列表。3. 核心组件与API初识在编写业务代码前先了解Flowable通过starter注入的几个核心Service Bean。这些是我们操作流程的入口。RepositoryService: 流程仓库服务。负责管理部署、查询、删除流程定义BPMN XML文件。RuntimeService: 运行时服务。负责启动流程实例、查询和操作运行中的流程实例、设置流程变量。TaskService: 任务服务。负责处理流程中产生的用户任务例如查询个人任务、完成任务、设置任务变量、指派任务等。HistoryService: 历史服务。查询已经执行完毕的流程实例、任务、活动实例等历史数据。IdentityService: 身份服务。管理用户、组以及它们之间的关系在简单集成中可能不直接使用。你可以在你的Controller或Service中直接通过Autowired注入这些服务。import org.flowable.engine.RepositoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RestController; RestController public class ProcessController { Autowired private RepositoryService repositoryService; Autowired private RuntimeService runtimeService; Autowired private TaskService taskService; // ... 后续的业务方法将使用这些Service }4. 手动创建并部署第一个BPMN流程在引入可视化编辑器之前我们先通过手动编写一个最简单的BPMN XML文件并部署到引擎中来理解整个机制。4.1 创建BPMN XML文件在src/main/resources目录下创建processes文件夹。Flowable默认会自动扫描该目录下的.bpmn20.xml或.bpmn文件进行部署。在processes文件夹内创建leave-application.bpmn20.xml文件。这是一个简化的请假流程开始 - 员工提交请假用户任务 - 经理审批用户任务 - 结束。?xml version1.0 encodingUTF-8? definitions xmlnshttp://www.omg.org/spec/BPMN/20100524/MODEL xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:flowablehttp://flowable.org/bpmn targetNamespacehttp://www.flowable.org/processdef !-- 定义一个流程id是流程的唯一标识在代码中引用 -- process idleaveApplication name请假申请流程 isExecutabletrue !-- 开始事件 -- startEvent idstartEvent name开始/ !-- 用户任务员工提交申请 -- !-- flowable:assignee${applicant} 表示任务处理人由变量applicant动态指定 -- userTask idsubmitLeaveTask name提交请假申请 flowable:assignee${applicant}/ !-- 用户任务经理审批 -- !-- flowable:candidateGroupsmanager 表示该任务候选组为“manager”组内成员可签收 -- userTask idmanagerApproveTask name经理审批 flowable:candidateGroupsmanager/ !-- 结束事件 -- endEvent idendEvent name结束/ !-- 顺序流连接各个节点 -- sequenceFlow idflow1 sourceRefstartEvent targetRefsubmitLeaveTask/ sequenceFlow idflow2 sourceRefsubmitLeaveTask targetRefmanagerApproveTask/ sequenceFlow idflow3 sourceRefmanagerApproveTask targetRefendEvent/ /process /definitionsXML标签解析process: 定义一个完整的业务流程。id属性在代码中用于启动流程isExecutable”true”表示该流程可被执行。startEvent/endEvent: 流程的开始和结束节点。userTask: 用户任务节点代表需要人工处理的任务。关键属性id: 任务节点ID在代码中用于查询特定任务。name: 任务显示名称。flowable:assignee: 任务签收人通常通过流程变量${variableName}动态指定。flowable:candidateGroups: 任务候选组组内的用户都可以看到并签收此任务。sequenceFlow: 顺序流定义节点间的连接线。sourceRef和targetRef分别指向源节点和目标节点的ID。4.2 编写API部署与启动流程创建一个REST Controller来提供流程部署和启动的接口。package com.example.demo.controller; import org.flowable.engine.RepositoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.repository.Deployment; import org.flowable.engine.runtime.ProcessInstance; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.HashMap; import java.util.Map; RestController RequestMapping(/api/process) public class ProcessController { Autowired private RepositoryService repositoryService; Autowired private RuntimeService runtimeService; /** * 部署流程定义如果已部署此操作会创建新版本 * return 部署结果 */ PostMapping(/deploy) public String deploy() { Deployment deployment repositoryService.createDeployment() .addClasspathResource(processes/leave-application.bpmn20.xml) // 指定资源 .name(请假流程部署) // 部署名称 .deploy(); // 执行部署 return 流程部署成功部署ID: deployment.getId() , 部署名称: deployment.getName(); } /** * 启动一个请假流程实例 * param applicant 申请人ID例如员工工号 * return 流程实例信息 */ PostMapping(/start) public String startProcess(RequestParam String applicant) { // 设置流程变量 MapString, Object variables new HashMap(); variables.put(applicant, applicant); // 与XML中的${applicant}对应 // 通过流程定义的Key来启动流程实例 ProcessInstance processInstance runtimeService.startProcessInstanceByKey(leaveApplication, variables); return 流程启动成功流程实例ID: processInstance.getId() , 流程定义ID: processInstance.getProcessDefinitionId(); } }代码解释deploy()方法使用RepositoryService将classpath下的BPMN文件部署到引擎中。部署操作会将XML解析成可执行的数据存入数据库ACT_RE_PROCDEF等表。每次部署都会生成一个新的流程定义版本。startProcess()方法使用RuntimeService启动一个流程实例。startProcessInstanceByKey(“leaveApplication”)中的”leaveApplication”对应BPMN XML中process标签的id属性。variables映射会传递给流程例如applicant变量被用于设置第一个用户任务的签收人。4.3 测试流程部署与启动启动SpringBoot应用。使用Postman或curl测试API。部署流程POST http://localhost:8080/api/process/deploy响应流程部署成功部署ID: xxxxx, 部署名称: 请假流程部署启动流程POST http://localhost:8080/api/process/start?applicantzhangsan响应流程启动成功流程实例ID: yyyyy, 流程定义ID: leaveApplication:1:zzzzz查看数据库启动后检查ACT_RU_TASK运行时任务表应该能看到一条NAME为“提交请假申请”ASSIGNEE_为zhangsan的任务记录。这说明流程实例已成功创建并停留在了第一个用户任务节点。至此我们已经完成了SpringBoot与Flowable工作流引擎的基础集成并成功通过代码部署和启动了一个简单的流程。然而手动编写和修改BPMN XML对于复杂的业务流程来说效率极低。在下一部分下篇我们将引入bpmn-js前端编辑器实现流程的可视化设计、编辑和部署从而构建一个完整的工作流管理平台。