多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Spring Boot 2.6.13 + MySQL 8 + Flowable 6.8.1 整合实战:从环境搭建到审批流跑通

Spring Boot 2.6.13 + MySQL 8 + Flowable 6.8.1 整合实战:从环境搭建到审批流跑通 简介本资源面向需要快速搭建工作流自动化环境的企业级Java开发者与学习者提供Spring Boot 2.6.13、MySQL 8与Flowable 6.8.1的整合工程并内置MySQL 8安装程序省去单独部署数据库的繁琐步骤。压缩包共29个文件约382.9MB以xml配置、java源码、class字节码、yml与properties配置为主另含jar依赖、iml工程文件及msi安装包覆盖从工程配置到数据库安装的完整链路。已有108人学习下载。借助该工程读者可参考Spring Boot自动配置与RESTful接口组织方式结合Spring Data JPA或MyBatis完成数据持久化并基于BPMN 2.0标准实践流程设计、任务管理与表单管理快速理解Flowable在真实项目中的集成思路与目录结构适合作为工作流项目的起步模板与排错参考。1. 从一次“版本打架”说起Spring Boot 2.6.13 MySQL 8 Flowable 6.8.1 到底难在哪如果你最近在搭一套带审批流的后台系统大概率会撞上这个组合Spring Boot 2.6.13、MySQL 8、Flowable 6.8.1。单看每个都不新鲜凑一起就出事——启动报DataSource找不到、Flowable 建表脚本卡在utf8mb4排序规则、springboot版本太高导致自动配置类路径变了。我见过太多人卡在“环境都装好了就是跑不起来”这一步最后怀疑人生。这篇笔记就干一件事把这三个东西从零到跑通一条完整审批流的最小路径讲清楚包括 MySQL 8 在 Windows 上的安装配置、Spring Boot 2.6.13 的依赖取舍、Flowable 6.8.1 的表结构在哪找、以及那些官方文档不会写的血泪坑。适合正在做 OA、工单、请假审批类项目的后端也适合被springboot 数据访问配置搞晕的新手。读完你能自己复现一套可用的环境知道每个参数为什么这么设翻车了知道去哪查。2. 环境底座MySQL 8 安装配置与 Flowable 建表前置动作2.1 Windows 10 上装 MySQL 8 的完整路径与两个必改项热词里mysql在windows10上怎么安装、mysql安装配置教程一直高居不下说明这一步劝退率极高。我一般不用mysql installer for windows那个图形化全家桶它默认装一堆用不上的东西还容易和已有服务冲突。直接下 ZIP Archive 版解压到D:\tool\mysql-8.0.xx-winx64然后手动初始化。先建my.ini放在解压目录根下[mysqld] basedirD:/tool/mysql-8.0.46-winx64 datadirD:/tool/mysql-8.0.46-winx64/data port3306 character-set-serverutf8mb4 collation-serverutf8mb4_0900_ai_ci default-authentication-pluginmysql_native_password [client] default-character-setutf8mb4这里有两个必改项。第一default-authentication-plugin必须设成mysql_native_password。MySQL 8 默认用caching_sha2_password而 Flowable 6.8.1 依赖的 JDBC 驱动版本如果偏旧握手阶段直接报Unable to load authentication plugin。第二collation-server用utf8mb4_0900_ai_ci别用utf8mb4_general_ci否则 Flowable 建表时某些索引长度会超限。初始化并注册服务# 以管理员身份打开 cmd进入 bin 目录 mysqld --initialize-insecure --console # 无密码初始化root 空密码方便首次登录 mysqld --install MySQL8 net start MySQL8--initialize-insecure生成空密码 root生产环境别这么干但本地开发省事。启动后立刻改密码并建库ALTER USER rootlocalhost IDENTIFIED BY YourStrongPass123; CREATE DATABASE flowable_demo DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; CREATE USER flow% IDENTIFIED BY Flow2024; GRANT ALL PRIVILEGES ON flowable_demo.* TO flow%; FLUSH PRIVILEGES;建库时显式指定utf8mb4_0900_ai_ci和my.ini保持一致。很多人库建完了才想起来改字符集Flowable 已经建了一半表再改就得删库重来这就是没有后悔药的地方。2.2 Flowable 6.8.1 表结构在哪找三张核心表先看懂flowable 表结构在哪找是高频问题。Flowable 启动时自动建表一共 70 多张按前缀分四类ACT_RE_*是仓库流程定义、模型ACT_RU_*是运行时执行实例、任务ACT_HI_*是历史ACT_GE_*是通用属性、字节数组。你不需要全背但有三张必须认识。ACT_RE_PROCDEF存流程定义每次部署一个 BPMN 文件就多一条记录KEY_字段是流程标识VERSION_是版本号。ACT_RU_TASK是当前待办任务ASSIGNEE_是处理人TASK_DEF_KEY_对应 BPMN 里 userTask 的 id。ACT_HI_PROCINST是流程实例历史START_TIME_、END_TIME_、DELETE_REASON_都在这里。验证建表是否成功直接查SELECT COUNT(*) FROM information_schema.tables WHERE table_schema flowable_demo AND table_name LIKE ACT_%; -- 正常应该在 70 左右如果数量明显偏少多半是databaseSchemaUpdate配置成了false或者数据库用户没有建表权限。Flowable 默认databaseSchemaUpdatetrue会自动执行建表脚本但生产环境建议改成false并手动执行flowable-mysql-create.sql避免每次启动都去校验。提示Flowable 6.8.1 的建表脚本在flowable-enginejar 包的org/flowable/db/create目录下解压 jar 就能看到不用去网上找。3. Spring Boot 2.6.13 整合 Flowable 6.8.1依赖、配置与启动顺序3.1 为什么选 2.6.13 而不是更高版本热词里springboot版本太高是个真实痛点。Spring Boot 2.7 之后自动配置机制调整Flowable 6.8.1 的flowable-spring-boot-starter里有些ConditionalOnMissingBean的判断逻辑对不上会出现ProcessEngine不创建但也不报错的玄学现象。2.6.13 是 2.6.x 最后一个补丁版和 Flowable 6.8.1 的兼容性经过大量项目验证属于稳妥选择。pom.xml关键依赖parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.6.13/version /parent properties java.version8/java.version flowable.version6.8.1/flowable.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.flowable/groupId artifactIdflowable-spring-boot-starter-process/artifactId version${flowable.version}/version /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency dependency groupIdcom.alibaba/groupId artifactIddruid-spring-boot-starter/artifactId version1.2.20/version /dependency /dependencies注意mysql-connector-java用 8.0.33别用 5.x。5.x 驱动连 MySQL 8 会报时区错误The server time zone value虽然加serverTimezoneAsia/Shanghai能绕过但驱动本身对caching_sha2_password支持不完整早晚出问题。3.2 application.yml 里四个不能省的参数spring: datasource: url: jdbc:mysql://localhost:3306/flowable_demo?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue username: flow password: Flow2024 driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource druid: initial-size: 5 max-active: 20 validation-query: SELECT 1 flowable: database-schema-update: true async-executor-activate: false history-level: full check-process-definitions: false四个关键点。allowPublicKeyRetrievaltrue必须加否则 MySQL 8 的caching_sha2_password在非 SSL 连接下拒绝握手。async-executor-activate: false本地开发关掉异步执行器避免定时任务干扰调试生产再开。history-level: full记录完整历史方便查流程轨迹代价是ACT_HI_*表增长快。check-process-definitions: false关掉自动扫描resources/processes目录改用手动部署控制更精细。启动类不需要额外注解flowable-spring-boot-starter-process会自动装配ProcessEngine。启动后看日志出现Flowable Process Engine和ProcessEngine default created就说明引擎起来了。如果只看到数据源初始化没有引擎日志检查依赖是否被spring-boot-starter-web的传递依赖覆盖了版本。3.3 手动部署一个 BPMN 并跑通第一条任务自动扫描关掉后用代码部署。先写一个最简单的请假流程leave.bpmn20.xml放在src/main/resources/processes下但因为我们关了自动扫描所以手动读Service public class LeaveProcessService { Autowired private RepositoryService repositoryService; Autowired private RuntimeService runtimeService; Autowired private TaskService taskService; // 部署流程定义 public String deploy() { Deployment deployment repositoryService.createDeployment() .addClasspathResource(processes/leave.bpmn20.xml) .name(请假流程) .deploy(); return deployment.getId(); } // 启动流程实例 public String start(String applicant) { MapString, Object vars new HashMap(); vars.put(applicant, applicant); ProcessInstance pi runtimeService.startProcessInstanceByKey(leaveProcess, vars); return pi.getId(); } // 查询待办并完成 public void complete(String taskId) { taskService.complete(taskId); } }repositoryService.createDeployment()每次调用都会新增一条ACT_RE_DEPLOYMENT记录如果同一个 BPMN 重复部署ACT_RE_PROCDEF的VERSION_会递增。开发阶段反复部署没问题生产环境建议用deploymentBuilder.enableDuplicateFiltering()去重。startProcessInstanceByKey的 key 对应 BPMN 里process idleaveProcess的 id写错会报no processes deployed with key。跑通验证调deploy()后查ACT_RE_PROCDEF应该有一条记录调start()后查ACT_RU_EXECUTION和ACT_RU_TASK各有一条调complete()后ACT_RU_TASK清空ACT_HI_TASKINST多一条历史。这条链路走通环境就算立住了。4. 避坑与排查五个让项目起不来的真实翻车记录4.1 启动报Table flowable_demo.ACT_GE_PROPERTY doesnt exist现象是应用启动直接失败日志里ACT_GE_PROPERTY不存在。原因是database-schema-update设成了false但你又没手动执行建表脚本。Flowable 启动时要读ACT_GE_PROPERTY里的版本号来判断是否需要升级表都没有自然读不到。解决本地开发设true让它自动建或者手动执行flowable-mysql-create.sql后再设false。别设成true又指望它建表却不给建表权限那是另一个坑。4.2 中文流程名乱码查出来是问号ACT_RE_PROCDEF的NAME_字段存中文变???。原因是建库时字符集不是utf8mb4或者 JDBC URL 里characterEncoding写成了utf8而不是utf8mb4。MySQL 的utf8是三字节存不下 emoji 和部分生僻字Flowable 的 XML 里如果有中文注释也可能触发。解决库、表、连接三层全部统一utf8mb4URL 里写characterEncodingutf8其实驱动会映射到utf8mb4但显式写connectionCollationutf8mb4_0900_ai_ci更稳。4.3ProcessEngine不创建但也不报错这是最玄学的一种。应用正常启动数据源正常但Autowired ProcessEngine注入失败或为 null。原因是 Spring Boot 2.6 的自动配置条件评估顺序变了flowable-spring-boot-starter-process里的ProcessEngineAutoConfiguration依赖DataSource和PlatformTransactionManager如果你自己定义了DataSource但没暴露PlatformTransactionManager条件不满足就静默跳过。解决检查是否有多余的EnableTransactionManagement或自定义事务管理器覆盖了默认的确保DataSourceTransactionManager被正确注册。4.4 启动时卡在AsyncExecutor线程池初始化日志停在Starting AsyncExecutor不动过一会超时。原因是async-executor-activate默认true异步执行器要连数据库建锁表如果数据库连接池max-active太小比如设成 1异步线程拿不到连接就死等。解决本地开发直接设false生产环境确保连接池至少 10 个连接并且async-executor的default-queue-size别设太大。4.5 重复部署导致版本号暴涨历史任务关联错乱每次重启应用都重新部署一次 BPMNACT_RE_PROCDEF的VERSION_从 1 涨到 50新启动的流程实例关联到最新版本但旧版本的历史任务查不到对应定义。原因是部署时没做去重。解决用enableDuplicateFiltering()它比对的是ACT_GE_BYTEARRAY里 BPMN 文件的字节内容内容没变就不新增版本。注意这个比对基于字节改一个空格都会触发新版本所以 BPMN 文件别用不同编辑器反复保存。5. 进阶技巧用 Flowable 的HistoryService做流程轨迹回溯与性能取舍环境跑通只是开始真正落地时产品会问“这个单子谁在什么时候转给谁的”。HistoryService就是干这个的但用不好会把ACT_HI_*表撑爆。我一般按需查不查全量。Autowired private HistoryService historyService; public ListMapString, Object trace(String processInstanceId) { ListHistoricActivityInstance activities historyService .createHistoricActivityInstanceQuery() .processInstanceId(processInstanceId) .orderByHistoricActivityInstanceStartTime().asc() .list(); ListMapString, Object result new ArrayList(); for (HistoricActivityInstance act : activities) { MapString, Object node new HashMap(); node.put(activityId, act.getActivityId()); node.put(activityName, act.getActivityName()); node.put(type, act.getActivityType()); node.put(assignee, act.getAssignee()); node.put(start, act.getStartTime()); node.put(end, act.getEndTime()); node.put(duration, act.getDurationInMillis()); result.add(node); } return result; }orderByHistoricActivityInstanceStartTime().asc()保证轨迹按时间正序前端画时间轴直接能用。getDurationInMillis()返回毫秒如果节点还没结束返回 null前端要判空。这个查询走ACT_HI_ACTINST表数据量大时加processInstanceId索引是必须的Flowable 建表时默认建了但如果你手动改过表结构要确认索引还在。性能取舍上history-level三个档位none不记历史ACT_HI_*表基本不写查轨迹没数据audit记流程实例和任务不记活动明细full全记包括变量更新。我一般生产用audit只在需要详细轨迹的流程上单独开full通过ProcessEngineConfiguration动态调整不现实更实际的做法是评估业务量日流程实例过万就慎用full。还有一个技巧ACT_HI_VARINST存历史变量每次setVariable都插一条如果流程里频繁改变量这张表膨胀最快。可以用historyService.createHistoricVariableInstanceQuery().processInstanceId(pi).list()按需查别在流程里无脑setVariable。注意ACT_HI_*表没有自动清理机制Flowable 提供了historyService.deleteHistoricProcessInstance()但会级联删任务和活动生产环境建议按时间分区或定期归档别等表过亿再处理。最后说个我自己的习惯每次搭新环境先只跑一个最简 BPMN确认ACT_RE_PROCDEF、ACT_RU_TASK、ACT_HI_PROCINST三张表有数据再往上叠业务逻辑。这样出问题时排查范围小不用在几十张表里大海捞针。这套组合不新但稳把版本锁死、字符集统一、部署去重这三件事做到位能省掉后面 80% 的玄学问题。希望帮到你。本文还有配套的精品资源点击获取
返回列表