尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

SpringBoot集成Activiti 7:工作流引擎落地实战与踩坑记录

发布时间:2026/9/10 17:11:51

资讯中心
01
ARTICLE

SpringBoot集成Activiti 7:工作流引擎落地实战与踩坑记录

SpringBoot集成Activiti 7:工作流引擎落地实战与踩坑记录
项目前后端都跑通了唯独审批流这块一直没有落地。挨个把市面上的工作流引擎调研了一遍最后还是选中了 Activiti 7。真把它往 SpringBoot 项目里塞的时候才发现网上教程一半停留在 Activiti 5/6另一半又拿 Flowable 来凑数。真正能照着敲的 Activiti 7 集成文章少得可怜。这篇就是我自己踩完坑之后沉淀下来的如果你的项目也要在 SpringBoot 里集成 Activiti 7并且不想在版本、配置、自动部署、事务边界这些地方反复折腾那这篇文章能帮你省下至少两三天时间。1. 为什么还在用 Activiti 7先把这个引擎的背景摸清楚1.1 工作流引擎解决的核心问题很多团队在没有引入工作流引擎之前审批逻辑是怎么写的一张表加一个状态字段status0待审、status1通过、status2驳回再配合几个接口到处 update。这种方案在流程固定、节点少于三个的时候确实没问题但一旦出现条件分支、会签、驳回回退、加签转办代码就开始失控了。工作流引擎的核心价值就是把流程怎么走这件事从业务代码里抽离出来交给一套独立的流程定义去描述业务代码只关心当前节点做什么。Activiti 是这套思路里非常典型的实现。它基于 BPMN 2.0 标准用 XML 描述流程节点、连线、网关、事件引擎负责解释和执行这些定义。对 Java 技术栈来说Activiti 的 Spring Boot Starter 集成起来很顺手社区资料又多这也是我一开始就把它纳入候选的重要原因。1.2 Activiti 的版本江湖5、6、7 和流出的 FlowableActiviti 的版本线有点乱搞清楚之后能少踩很多坑。Activiti 5 是当年 Alfresco 开源的那一代资料最多大部分老教程都是基于它写的。Activiti 6 团队做了大重构但没火起来。到了 Activiti 7官方把引擎拆得更开主推云原生方向同时把 Spring Boot Starter 作为一等公民来支持。但是这里有个关键背景Activiti 的核心开发团队在 5/6 时代就分家出去做了 Flowable所以社区里一直有Activiti 后继乏力Flowable 更活跃的说法。实话说Flowable 的迭代速度和社区活跃度确实更高但 Activiti 7 依然有不少存量项目和完整的企业版方案在用网上资料、书籍、问题解答也都够用。对一个要快速落地审批流的团队来说选 Activiti 7 完全说得过去。1.3 什么项目适合选 Activiti 7根据我这次的实践经验如果你的项目满足下面几个条件选 Activiti 7 比较稳技术栈是 SpringBoot 2.x没有强行上 SpringBoot 3流程模型以 BPMN 2.0 为主不依赖特别花哨的引擎特性团队里没有专门研究过 Flowable 的高级开发项目周期紧希望靠成熟的资料和现成代码快速跑通。反过来说如果你刚起新项目、团队愿意花时间研究Flowable 的综合体验确实更好这一点我不回避。但这个选择问题我放到最后一章细说先把集成跑通这件事讲透。2. 第一道坎SpringBoot 版本太高Activiti 7 带不动2.1 为什么 SpringBoot 3.x 直接翻车搜索springboot版本太高这个关键词的人大概率就是在这里卡住了。Activiti 7 的 Spring Boot Starter 是跟着 SpringBoot 2.x 时代走的内部用的是javax.*命名空间而 SpringBoot 3.x 全面切到了jakarta.*。这不是改一行配置能解决的而是整个底层 API 的迁移。换句话说你把activiti-spring-boot-starter直接丢进 SpringBoot 3 的项目里启动阶段就会报 ClassNotFoundException 或者 NoSuchMethodError跟你的代码没关系就是版本兼容问题。所以我的第一个建议是集成 Activiti 7老老实实用 SpringBoot 2.x。这不是保守是避免给自己找麻烦。如果你因为公司规范必须上 SpringBoot 3那就直接放弃 Activiti 7去看 Flowable 7 或者 Flowable 6.8那边对 Jakarta 的适配已经做了。2.2 我的选型配置与完整依赖我用的是 SpringBoot 2.5.12 和 Activiti 7.1.0.M6。SpringBoot 2.5.x 是当前存量项目里覆盖率很高的版本和 Activiti 7.1.0.M6 配合稳定网上踩坑记录也最齐全。pom.xml 里的核心依赖就两个dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.activiti/groupId artifactIdactiviti-spring-boot-starter/artifactId version7.1.0.M6/version /dependency启动器会自动把引擎相关的依赖带进来包括 MyBatis、HikariCP 这些。我这边数据源用的是 MySQL 8所以还要加 MySQL 驱动dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency这里有个容易忽略的点如果你的项目里同时引入了mybatis-spring-boot-starter要注意 SqlSessionFactory 的冲突。Activiti 引擎内部用自己的 MyBatis 配置业务代码如果又起了一套 MyBatis两边的 SqlSessionFactory 可能互相覆盖。最简单的处理方式是业务模块不要用 MyBatis换 JPA 或者纯 JDBC如果业务模块必须用 MyBatis那就需要做多数据源隔离把 Activiti 的 SqlSessionFactory 和业务 SqlSessionFactory 分开管理。这个我后面还会提到。2.3 启动验证日志里出现什么才说明引擎起来了SpringBoot 项目启动后观察控制台日志。Activiti 7 启动器会自动初始化过程引擎并执行自动建表。正常情况下日志里会出现类似下面的内容ProcessEngine created [default] Activiti Schema upgrade successful如果配置了spring.activiti.database-schema-updatetrue对应的ACT_RE_*、ACT_RU_*、ACT_HI_*、ACT_GE_*这些表会自动创建出来。我第一次启动的时候看到数据库里唰唰出现了几十张ACT_开头的表心里才算踏实。application.yml 里我建议这样配spring: datasource: url: jdbc:mysql://localhost:3306/activiti?useUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghai username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver activiti: database-schema-update: true db-history-used: true history-level: audit check-process-definitions: true这里解释一下几个配置项的意义。database-schema-updatetrue表示引擎启动时自动检查并升级表结构首次部署用这个最省事。db-history-usedtrue是启用历史表history-levelaudit表示记录流程实例和活动实例的完整历史默认值就是这个一般不用改。check-process-definitionstrue是让引擎启动时扫描并自动部署流程定义文件这个机制下一章细说。3. 自动部署流程定义文件放对位置部署代码都可以省3.1 resources/processes 目录约定与文件名规则Activiti 的 Spring Boot Starter 有一个约定把 BPMN 流程文件放在resources/processes/目录下启动时引擎会自动扫描并部署它们。这个机制是基于check-process-definitionstrue的默认行为扫描后缀为.bpmn20.xml和.bpmn的文件。文件名规则值得注意。我用的是leave.bpmn20.xml这种格式引擎会把它识别为一个 BPMN 2.0 流程定义。如果你用.bpmn后缀也能识别但部分编辑器生成的.bpmn文件头和 schema 版本不一致可能导致解析失败。在团队协作时我建议统一用.bpmn20.xml后缀最稳。另一种自动部署的隐藏坑是如果你把流程文件放在resources/下的其他目录或者用classpath*:processes/*.bpmn20.xml这种自定义路径必须在配置文件里显式指定spring: activiti: custom-process-definition-resource-prefix: classpath*:/processes/否则引擎只会扫默认目录你的流程文件写了也白写。3.2 手动部署与动态 XML 部署自动部署适合流程文件相对固定的场景但真实项目里经常需要手动部署比如管理员上传一个新的流程包而不是重启应用。手动部署的代码很简单Autowired private RepositoryService repositoryService; public void deployFromClasspath() { Deployment deployment repositoryService.createDeployment() .name(请假流程) .addClasspathResource(processes/leave.bpmn20.xml) .deploy(); System.out.println(deployment.getId()); }还有一种常见需求流程 XML 存在数据库或者配置中心里不打包到 classpath。这时候可以从字符串部署public void deployFromXmlString(String processName, String xmlContent) { repositoryService.createDeployment() .name(processName) .addString(leave.bpmn20.xml, xmlContent) .deploy(); }从字符串部署时文件名不要乱起末尾这个字符串会被引擎用来识别资源类型建议保持.bpmn20.xml结尾。3.3 流程版本管理deploymentId、key、version 的关系每次部署同一个流程定义引擎会自动生成一个新版本版本号从 1 开始递增。这里的几个概念经常让人绕晕deploymentId是每次部署动作的唯一标识一次部署对应一个 deploymentId。processDefinitionKey是流程定义 XML 里process idleave的 id它是流程的业务标识。version是同一个 key 下的版本递增序号。启动流程实例时默认使用该 key 下的最新版本。如果你要指定老版本启动可以用startProcessInstanceById(processDefinitionId)其中processDefinitionId deploymentId:version组成的一长串。实际项目里流程定义升级是常态但要注意流程实例一旦启动就绑定当前版本已经流转到一半的实例不会自动切换到新版本。所以每次修改流程定义之前最好是先确认没有未完成的旧实例或者在流程设计上预留兼容。4. 核心 API 实战一个请假审批流程从发起走到结束4.1 流程设计请假审批的节点和分支只看 API 不看完整流程不够直观我拿一个请假审批流程来跑通全链路。这个流程包含四个核心节点员工填写请假申请作为流程发起人也是第一个用户任务的办理人。直属领导审批审批结果有两个出口同意继续、驳回直接结束。条件网关判断请假天数超过 3 天进入部门经理审批否则直接通过。部门经理审批通过则流程结束。在真实项目里流程还应该有结束通知事件、会签、加签但这里聚焦集成骨架先跑通最核心的链路。流程定义的关键部分可以用一句话概括process idleave name请假流程 isExecutabletrue里面的节点和连线用 BPMN 2.0 标准描述即可。建模工具推荐 IDEA 插件actiBPM或者在线工具画完导出 XML再把它放进resources/processes/。4.2 发起流程set 变量与 processInstanceBusinessKey流程发起是引擎最常用的入口。假设用户提交了一个请假申请业务系统先把申请数据落库然后调用引擎启动一个流程实例Autowired private RuntimeService runtimeService; public void startLeaveProcess(LeaveApplyDTO dto) { MapString, Object variables new HashMap(); variables.put(applyUser, dto.getUserId()); variables.put(manager, dto.getManagerUserId()); variables.put(days, dto.getDays()); variables.put(deptManager, dto.getDeptManagerUserId()); ProcessInstance processInstance runtimeService.startProcessInstanceByKey( leave, dto.getBusinessKey(), variables ); }startProcessInstanceByKey的第一个参数是流程定义 key第二个参数是业务主键businessKey。强烈建议流程实例和业务数据用businessKey关联起来一是排查问题方便二是后续自定义查询可以直接靠 businessKey 反查业务表而不是维护一张流程实例和业务记录的映射表。businessKey在流程实例的整个生命周期里都不会变是天然的外键。variables里的这些变量后续会被流程表达式引用比如用户任务的candidateGroups、条件网关的days 3。变量类型建议用 String、Integer、Boolean 这些基础类型引擎持久化时按类型走不同的策略复杂对象容易导致序列化问题。4.3 查询待办taskAssignee 与 candidate 的区别流程启动后第一个用户任务会自动分配给applyUser指定的办理人。待办查询用 TaskServiceAutowired private TaskService taskService; public ListTask queryTodoList(String userId) { return taskService.createTaskQuery() .taskAssignee(userId) .processDefinitionKey(leave) .orderByTaskCreateTime() .desc() .list(); }这里有一点必须搞清楚taskAssignee是任务的指定办理人taskCandidateUser是候选人taskCandidateGroup是候选组。在流程定义里如果你的用户任务设置了activiti:candidateGroupsmanagerGroup那查询时要用taskCandidateGroup或taskCandidateUser否则查不到。实际项目里待办查询很容易写成用户能看到任务的集合这个用户既是某些任务的直接办理人又是某些任务的候选人。这时候可以用taskCandidateOrAssigned(userId)来合并查询Activiti 7 提供了这个 API。我一开始没注意导致候选人身份的任务一直查不出来后来发现是查询条件用错了。4.4 审批通过、驳回与历史查询拿到任务 ID 之后审批动作本质就是完成任务并设置流程变量public void completeTask(String taskId, boolean approved, String comment) { MapString, Object variables new HashMap(); variables.put(approved, approved); variables.put(comment, comment); taskService.complete(taskId, variables); }驳回逻辑并不需要单独接口只需要让流程网关根据approved变量走不同分支。示例流程里直属领导审批节点后面接一个排他网关approved false时走向结束事件approved true时继续判断请假天数。这样同一个complete调用就天然完成了批准或驳回两条链路。流程跑完之后要查历史状态和审批记录用 HistoryServiceAutowired private HistoryService historyService; public ListHistoricActivityInstance queryHistory(String processInstanceId) { return historyService.createHistoricActivityInstanceQuery() .processInstanceId(processInstanceId) .orderByHistoricActivityInstanceEndTime() .asc() .list(); }HistoricActivityInstance里能拿到每个节点的开始时间、结束时间、办理人、活动类型这就是审批记录的原始数据。再做一层组装就可以输出张三点提交、李四已审批、王五已审批这样的时间轴。5. 流程引擎和业务代码的事务一致性5.1 为什么必须同事务流程实例和业务数据不能打架工作流引擎真正考验开发功底的地方不是把流程跑起来而是让流程实例和业务数据始终保持一致。举个例子用户提交请假申请业务系统保存了请假单然后调runtimeService.startProcessInstanceByKey启动流程。如果保存业务数据成功但启动流程时抛了异常用户看到的结果是单子已经提交了但流程根本没转起来后台数据对不上后续全部乱套。正确做法是把业务操作和流程操作放同一个事务里Service public class LeaveService { Autowired private LeaveApplyMapper leaveApplyMapper; Autowired private RuntimeService runtimeService; Transactional(rollbackFor Exception.class) public void submitLeave(LeaveApplyDTO dto) { leaveApplyMapper.insert(dto); MapString, Object variables new HashMap(); variables.put(applyUser, dto.getUserId()); variables.put(manager, dto.getManagerUserId()); variable.put(days, dto.getDays()); runtimeService.startProcessInstanceByKey(leave, dto.getBusinessKey(), variables); } }Transactional注解保证业务插入和流程启动要么都成功要么都回滚。Activiti 引擎内部本身是支持 Spring 事务管理的在同一个事务上下文里它用的数据源和业务数据源如果配置成同一个回滚也能一致生效。5.2 事务失效的几种写法我基本都踩过springboot 事务失效场景这个话题在搜索热度里居高不下我在集成过程里也踩过同款坑。最典型的几个场景第一种是方法内部自调用。同一个类里 A 方法调用带Transactional的 B 方法因为 A 方法通过this调用没有经过 Spring 代理事务注解根本不生效。解决方式是把 B 方法挪到另一个 Service或者注入自己的代理对象。第二种是异常被吞掉。Transactional只能回滚 RuntimeException 和 Error如果你在方法里catch了异常还继续执行事务不会回滚数据照样提交。这不是玄学是对 Spring 事务默认回滚规则的误解。最好的做法是异常不要吞要么直接抛出要么TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()手动标记回滚。第三种是方法不是public。private方法上的Transactional注解不会生效Spring 的 AOP 代理只对public方法生效。第四种是在另一个线程里执行流程操作。事务和线程绑定跨线程调用事务回滚不会传递到外层线程。如果流程发起是异步任务要么保证异步任务内部自己管理事务要么接受业务数据先落、流程实例在异步任务里启动的事实并做好补偿机制。5.3 循环依赖SpringBoot 2.6 后的默认限制springboot 循环依赖这个关键词也比较火核心是 SpringBoot 2.6 之后默认禁止了 Bean 之间的循环依赖。在实际项目里最容易出现这个问题的地方是业务 Service 依赖流程服务流程服务又反过来依赖业务 Service。我的建议是不要用Lazy投机取巧而是从设计上切断循环依赖流程服务只依赖引擎自带的 Service不依赖具体的业务 Service。业务 Service 单向依赖流程服务流程服务通过事件监听器或消息机制反向通知业务模块。如果实在绕不开再考虑Lazy注入。Activiti 本身支持事件监听机制流程节点流转时会发出各类事件业务模块可以监听这些事件来更新状态而不是让流程服务主动调用业务方法。这样既解决了循环依赖也让模块间的耦合度降下来值得花心思做。6. 踩坑实录这几个问题最折磨人6.1 启动不建表启动日志里没有Activiti Schema upgrade successful数据库里也没有ACT_开头的表。优先检查两件事数据源连接是否正常。Activiti 的表是直接创建在配置的 datasource 上的如果你连错了库引擎会连表都找不到。spring.activiti.database-schema-update是否设置。默认值是true但有的团队会在公共配置里把它改成false导致新环境根本不会建表。另外如果项目里有多个数据源Activiti 默认使用主数据源要注意它建到的库是不是你要的库。6.2 流程文件没自动部署流程文件放在resources/processes/下启动后ACT_RE_PROCDEF表却是空的。这个问题多半是文件名后缀不对或者放错了模块。多模块项目里流程文件如果在公共模块默认扫描可能不生效需要在配置里指定资源路径spring: activiti: custom-process-definition-resource-prefix: classpath*:**/processes/*.bpmn20.xml这里用classpath*:前缀很关键单星号classpath:只能扫第一个 jar 里的资源多模块时会漏。6.3 DTYPE 字段引发的持久层报错Activiti 的内核基于 JPA/Hibernate 时代的设计部分表结构里保留了DTYPE字段用于区分继承关系。在一些组合场景下比如同时引入了 Hibernate 相关依赖或者数据库方言切换时会报类似DTYPE无法识别的错误。这个问题没有统一的解决办法我遇到时是通过检查数据库表结构的实际列确认DTYPE是否被其他框架的建表策略覆盖掉。排查思路是先确认表是 Activiti 引擎自建的还是被 Hibernate 或 Flyway 抢先建了。如果是 Flyway 管理的数据库最好把 Activiti 的表排除在 Flyway 的版本控制之外避免两边建表逻辑冲突。6.4 中文乱码和时区问题流程定义名称、审批意见、任务描述里带中文查出来乱码十有八九是 JDBC URL 没有指定编码或者编辑器保存的 BPMN 文件不是 UTF-8。确认下面两点spring: datasource: url: jdbc:mysql://localhost:3306/activiti?useUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghai时区问题也同样重要不设置serverTimezoneMySQL 8 默认的时区是 UTC流程时间记录会比本地时间少 8 小时。查询历史记录时你会发现所有时间都对不上最后排错排到怀疑人生。6.5 每次重启都重新部署流程版本疯涨开发阶段每次重启应用ACT_RE_PROCDEF里的版本号就 1版本越堆越多。这是因为自动部署机制在每次启动时都会重新解析resources/processes/下的文件并部署一次。开发环境可以接受但生产环境如果也这样会积累一堆垃圾版本。两种处理方式流程变更不频繁的项目把流程文件从依赖包里拆出来放到配置中心或数据库用手动部署的方式管理。如果流程文件就是跟随代码发布那么每次发布新版本本来就是流程定义的变更版本积累不算问题但要定期清理历史版本定义。清理历史版本不建议直接删表可以通过 RepositoryService 的 API 查询并删除不用的流程定义避免残留数据影响正常查询。7. 流程数据量上来之后不再只靠 TaskService 查列表7.1 NativeQuery 的场景与写法后台管理页面通常有我的待办所有流程实例已办任务这类列表条件组合很灵活光靠 TaskService 自带的链式查询往往不够用。Activiti 提供了 NativeQuery 方式可以直接写 SQL 补充过滤条件。比如按业务表单里的某个编号查待办任务ListTask tasks taskService.createNativeTaskQuery() .sql(SELECT * FROM managementService.getTableName(Task.class) T WHERE T.ASSIGNEE_ #{userId} AND T.PROC_INST_ID_ IN (SELECT ID_ FROM ACT_HI_PROCINST WHERE BUSINESS_KEY_ LIKE #{keyword})) .parameter(userId, userId) .parameter(keyword, % keyword %) .list();这么写的优点是灵活缺点是引擎表结构一旦变化SQL 可能崩。用了之后要把 SQL 收敛在一个查询层里别散落在业务代码各处。7.2 直接查历史表的自定义统计除了待办和已办后台还经常要看各类流程的发起量、平均审批时长、节点滞留时间这类统计。这种聚合查询用 TaskService 拼 API 很别扭不如直接对ACT_HI_PROCINST和ACT_HI_ACTINST做 SQL 聚合。引擎表虽然是 Activiti 内部结构但读取历史表做统计是相对安全的操作前提是项目约定不直接写这些表。统计 SQL 的要点是END_TIME_为空代表流程还在跑ACT_HI_ACTINST里的ACT_TYPE_区分任务节点、网关、事件节点DURATION_字段直接存了毫秒数算平均耗时很方便。这里有个真实的业务场景统计上个月请假流程的平均审批时长。对应的 SQL 逻辑可以写成从ACT_HI_PROCINST中筛出START_TIME_在目标月份的流程关联ACT_HI_ACTINST取每个任务节点的DURATION_求平均。不用纠结引擎内部对每个节点的记录粒度DURATION_是现成的。7.3 列表分页与性能建议流程数据量一大待办列表接口一定要做分页。TaskQuery 本身支持分页PageTask page new Page(pageNum, pageSize); ListTask tasks taskService.createTaskQuery() .taskAssignee(userId) .orderByTaskCreateTime() .desc() .listPage((int) page.getCurrent(), (int) page.getSize()); long total taskService.createTaskQuery() .taskAssignee(userId) .count();两个调用的查询条件必须完全一致否则 total 和列表对不上。性能上有一个容易被忽视的点listPage的 offset 过大会导致深分页问题。Activiti 的引擎表在TASK_ASSIGNEE_、PROC_INST_ID_上有索引但组合条件多了之后还是可能慢。我的做法是对待办列表的查询条件做精简用户进来默认只能看 30 条条件筛选放在后端做二次过滤不把全部数据拉回内存。8. 关于 Activiti 7 和 Flowable 的选择建议8.1 两者到底差在哪flowable和activiti区别是每次聊工作流都绕不开的问题。两者的血缘关系很有意思Flowable 是从 Activiti 5/6 时代的核心团队分出来的也就是说同一批人换了个项目继续做因此 Flowable 的底层架构和 API 设计跟 Activiti 6 一脉相承熟悉 Activiti 的人切 Flowable 的成本并不高。几个关键差异社区活跃度Flowable 的更新频率、Issue 响应速度明显快于 Activiti 7。SpringBoot 3 / Jakarta 适配Flowable 早已适配Activiti 7 仍停留在 javax 时代无法直接跑在 SpringBoot 3 上。云原生Activiti 7 官方主推的方向是 Activiti Cloud而 Flowable 提供了更丰富的 Spring Boot 集成和独立部署方案。企业级功能两者都有商业版但 Flowable 的开源版本已经包含了不少高级特性比如 CMMN 案例管理、DMN 决策表。对比维度Activiti 7FlowableSpringBoot 3 / Jakarta不支持需 2.x支持社区活跃度偏慢活跃BPMN 2.0支持支持CMMN / DMN商业版有开源较少开源版覆盖更多学习资料老资料多7.x 专属资料少官方文档齐全社区教程多部署方式Starter / CloudStarter / 独立 / Cloud8.2 什么情况下继续用 Activiti 7如果项目技术栈锁定在 SpringBoot 2.x且团队里已经积累了 Activiti 5/6 的代码和经验那继续用 Activiti 7 是最低成本的路径。存量系统迁移到 Flowable 虽然表面是换依赖但涉及流程定义兼容、历史表梳理、API 替换工作量和风险都不小。再加上 Activiti 7 完全能满足 BPMN 审批流的常规需求没必要为了新而换。另外如果你们只是需要一个稳定的引擎跑审批流程不想在引擎本身花太多维护精力Activiti 7 的稳定性足够。它的问题不是不能跑而是不更新对很多业务系统来说这反而是优点。8.3 什么情况下果断切 Flowable新项目、新团队、没有历史包袱我建议直接上 Flowable。理由很实际SpringBoot 3 是未来方向Flowable 已经做好了 Jakarta 适配新项目可以用最新版本不会一上来就碰到版本天花板Flowable 的官方文档比 Activiti 7 清晰得多这对刚开始接触工作流引擎的团队来说非常重要。如果你在调研阶段发现项目需要 CMMN 或者 DMN那就更应该直接选 Flowable。Activiti 7 的开源版本对这两块的支持不完整业务做到一半发现引擎能力不够再迁移的成本就很高了。如果让我给一个粗暴的结论项目已经在用 Activiti 且没出大问题继续用新项目需要选型优先 Flowable。工作流引擎只是工具能支撑业务稳定跑起来、团队能维护比追逐新版本重要得多。最后再分享一点个人体会。集成 Activiti 7 的过程中最消耗时间的其实不是引擎本身而是版本兼容和事务边界这类基础设施问题。选型前先确认好 SpringBoot 版本把自动部署机制理解透代码里保证流程操作和业务操作的事务一致这三个点做到位后面基本就是按部就班地写 API 了。流程引擎这种东西跑通 demo 只是开始真正能放心交给用户的是那些边界条件都被测试覆盖过的稳定版本。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。