资讯详情

Activiti6零基础入门:工作流引擎与BPMN审批流实战指南

📅 2026/11/3 22:09:39 | 华诺云谱 👁 阅读
Activiti6零基础入门:工作流引擎与BPMN审批流实战指南
简介「Activiti6 中文用户指南.docx」面向使用 Activiti6 进行业务流程管理开发的中高级 Java 工程师、架构师与 BPMN 学习者针对官方英文文档阅读成本高、配置与 API 细节分散的问题提供系统化的中文参考。文档围绕流程引擎的核心使用路径展开涵盖环境准备与快速入门、ProcessEngine 与数据库/JNDI/Job Executor 配置、Process Engine API 与查询、Spring 与 Spring Boot 集成、BAR 部署及版本控制并对 BPMN 2.0 的事件、边界事件、中间捕获与抛出等构造给出中文说明目录层级清晰便于按主题检索和查漏补缺。压缩包内为 1 个 docx 文件约 4.22MB适合作为日常开发中的案头手册与版本对照资料。目前已有 1816 人学习说明其在 Activiti 学习群体中具有一定参考价值。1. 先弄明白一件事Activiti6 到底是个什么东西很多人第一次打开 Activiti6 中文用户指南是在工作群里被丢了一个 docx后面跟一句「你先看看下周要用」。目录一拉BPMN 2.0 构造、REST API、Spring 集成、事件监听器、边界事件……几百个条目排下来第一反应往往是「这我怕是学不会」。先把话说白Activiti6 是一个跑在 Java 上的工作流引擎它把「谁先干、干完交给谁、超时了怎么办」这条线从你的业务代码里抽出来单独管起来。你画一张流程图引擎按图推进谁该收待办、谁点了同意、流程走到哪一步它都替你记着。它适合写 Java 后端、要做审批流、工单、报销、入职这类「一件事要经过好几个人」的人。零基础也能上手因为它的第一课不是写代码而是先看懂一张图。2. 为什么值得学它替你管住了哪些麻烦事新手最容易犯的嘀咕是「我自己写 if-else 也能审批为什么还要多学一个框架」。这个疑问很合理也值得认真回答因为如果答案只是「因为它流行」那确实没必要学。真正的原因是审批这类业务的复杂度不在「判断通过还是不通过」而在「流程本身会变、会分叉、会超时、会撤回、要留痕」。这些事一旦散落在业务代码里就会变成一团谁都不敢动的逻辑。下面用一张请假单把这件事讲清楚。2.1 一张请假单说清工作流到底在管什么假设你要做一个请假功能。最初的需求很简单员工提交主管审批通过就结束。你写了一个 status 字段0 是待审批1 是已通过2 是已驳回很清爽。两周后产品来了请假超过三天要主管加部门经理两级审批。你加了一个字段和一个 if。再过两周经理出差时要有代理人。再过两周驳回后员工可以修改再提交但要走原来的审批人。再过两周要能查到「这张单子在谁手上停了多久」。到这一步你的代码里会出现十几个状态字段、嵌套四五层的判断、一张谁也不敢删的抄送表以及一堆「历史记录」的补丁。这就是没有工作流引擎时的典型形态很多团队的血泪经验都在这儿。Activiti6 做的事情是把上面这些变化从代码里搬到一张图上状态、分支、超时、代理人、历史记录都由引擎按图执行你的代码只负责「审批通过后扣假期余额」这种真正的业务动作。改流程的时候你改的是图不是 Java 逻辑。这个差别在项目第一版看不出来在第六版会救命。所以学它的收益不是「会用一个框架」而是「以后遇到流程类需求你知道有一整套现成的抽象可以套」。2.2 学它之前你真正需要准备的东西只有三样很多新手卡在起点是因为以为要先补一大堆前置知识。其实按用户指南第 1 章的「所需软件」来看门槛低得超出预期一个 JDK 7 或更高版本的 Java 运行环境、一个你顺手的集成开发环境、一个能连上的数据库。就这些。你现在电脑上装的 JDK 大概率已经是 8 或更高版本直接满足要求IDE 用哪个都行用户指南里提到 Eclipse 和 IntelliJ IDEA 两类选你习惯的那个数据库更简单第一轮跑通完全可以用它自带的内存数据库 H2连安装都省了。真正不需要提前掌握的不用先啃完 BPMN 2.0 规范不用先学 Spring不用先搞懂数据库表结构。我见过不少人抱着规范文档看了三天一个流程都没跑起来然后放弃了。正确的顺序反过来先跑通一个最小流程回头再看规范你会发现那些符号都有具体对应物而不是抽象的图形学。入门建议先准备一个能跑 Java 的项目骨架Maven 或 Gradle 都行。如果你是纯新手连项目都不会建那就先用最简单的 Maven 项目模板加一个依赖能跑出 Hello World 就够了。这一小步过了后面的路会顺很多。2.3 这份中文用户指南能帮你省掉哪些弯路用户指南这种文档新手最容易犯的错是从第一页顺序读到最后一页。它不是教材是手册正确用法是「带着问题翻」。但中文版的价值恰恰在这里当你想查「任务怎么分配给某个人」时英文文档里 assignee、candidate user、candidate group 这几个词会绕晕你中文版直接告诉你这是「用户分配」和「用于任务分配的 Activiti 扩展」一眼就能对上你脑子里的那个概念。从目录结构也能看出一份学习地图第 1 到 3 章是环境、配置、数据库第 4 章是 API 和服务第 5 章是 Spring 集成第 6 章是部署第 7 章是 BPMN 十分钟教程第 8 章才开始讲各种事件和网关的细节。这个顺序本身就是作者给的学习路径——先能跑再能配然后才是各种花样。你如果是零基础就按这个顺序走别一上来翻到第八章看边界事件那就像还没学会走路先研究跑步姿势。还有一点很实在中文版里把「一分钟版」这种快速体验单独列了一节。它存在的意义就是让你在十分钟内看到界面、点到待办、完成一次审批先获得「这东西能用」的确认感再回头补理论。这个心理顺序对新手特别重要。3. 零基础跑通第一个例子从 war 包到登录后台这一章是全篇最该动手的部分。我把它拆成三步先用现成的界面看效果再用代码建引擎最后部署一个自己画的流程。三步都跑完你对 Activiti6 的理解会从「听说」变成「用过」。3.1 第一步把 war 包丢进容器用默认账号登进去用户指南的「一分钟版」讲的正是这件事步骤简单到有点不真实。你需要一个 Java 运行环境和一个 Web 容器常用的是 Tomcat实际上任何只依赖 servlet 功能的容器都能跑。把发布包里那个 activiti-app.war 复制到容器的 webapps 目录然后启动容器。# 假设 Tomcat 装在 /opt/tomcatwar 包已复制到 webapps 下 cd /opt/tomcat/bin # Windows 下用 startup.batLinux/macOS 下用 startup.sh ./startup.sh # 看到容器启动完成的日志后浏览器访问 # http://localhost:8080/activiti-app # 默认账号 admin默认密码 test这段命令没什么玄机startup.sh就是启动容器war 包会被自动解压部署访问路径由 war 包名决定——activiti-app.war对应/activiti-app。登录进去之后你会看到一个带流程设计器、任务列表、流程实例管理的后台界面这就是官方演示应用。提示这个演示应用默认用内存数据库 H2所有数据只活在内存里容器一重启就全没了。这是它的设计不是 bug用来体验刚好但你要是拿它当正式环境第二天发现数据消失那就是给自己找麻烦。这一步的意义在于你不用写一行代码就能看到「流程定义长什么样、待办任务在哪里点、历史记录怎么查」。很多人学框架卡住就是因为一开始全是抽象概念脑子里没有画面。先把画面建立起来后面的代码才有地方挂。3.2 第二步写代码创建第一个 ProcessEngine看完界面回到代码。Activiti6 的核心是一个叫 ProcessEngine 的对象你可以把它理解成「引擎本体」所有的服务、配置、数据库连接都从它身上长出来。创建一个最小可用的引擎只需要一个依赖加几行代码。!-- pom.xml 里加这一个依赖它会带进引擎核心和相关依赖 -- dependency groupIdorg.activiti/groupId artifactIdactiviti-engine/artifactId version6.0.0/version /dependencyimport org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngineConfiguration; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; import org.activiti.engine.TaskService; public class FirstEngine { public static void main(String[] args) { // 用「独立内存」配置起步不依赖外部数据库最适合第一次跑 ProcessEngineConfiguration cfg ProcessEngineConfiguration .createStandaloneInMemProcessEngineConfiguration() // H2 内存库DB_CLOSE_DELAY-1 表示连接关了库也别销毁 .setJdbcUrl(jdbc:h2:mem:activiti-demo;DB_CLOSE_DELAY-1) // true 启动时自动建表第一次跑必须开 .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); // 构建引擎这一步会自动创建 activiti 需要的所有表 ProcessEngine engine cfg.buildProcessEngine(); // 三个最常用的服务先拿到手 RepositoryService repositoryService engine.getRepositoryService(); // 管流程定义和部署 RuntimeService runtimeService engine.getRuntimeService(); // 管运行中的实例 TaskService taskService engine.getTaskService(); // 管待办任务 System.out.println(引擎启动成功 engine.getName()); engine.close(); } }几个参数值得单独说一下。createStandaloneInMemProcessEngineConfiguration()是「不依赖 Spring、用内存数据库」的快捷配置专门为快速验证准备setJdbcUrl里的DB_CLOSE_DELAY-1是 H2 的连接参数不加的话数据库连接一断表就没了第一次跑很容易在这里翻车setDatabaseSchemaUpdate(DB_SCHEMA_UPDATE_TRUE)控制建表策略设成 true 表示引擎启动时检查表结构缺表就建这对新手最友好但生产环境要谨慎。跑通这一步的标志是控制台打出「引擎启动成功」同时日志里能看到一串建表语句。看到那些act_开头的表名说明引擎已经把家底铺好了。3.3 第三步部署一个最简单的 BPMN 流程并启动它有了引擎接下来画一张最小的流程图。请假审批太典型了就用它提交申请、主管审批、结束。?xml version1.0 encodingUTF-8? definitions xmlnshttp://www.omg.org/spec/BPMN/20100524/MODEL xmlns:activitihttp://activiti.org/bpmn targetNamespacehttp://demo.example.com/leave !-- id 就是后面代码里启动流程用的 key全项目唯一 -- process idleaveProcess name请假审批 isExecutabletrue startEvent idstart name提交申请/ sequenceFlow idflow1 sourceRefstart targetRefleaderApprove/ !-- activiti:assignee 指定这步由谁处理这里写死成 leader实际项目一般用变量 -- userTask idleaderApprove name主管审批 activiti:assigneeleader/ sequenceFlow idflow2 sourceRefleaderApprove targetRefend/ endEvent idend name结束/ /process /definitions把这个文件存成leave.bpmn20.xml放到src/main/resources下。文件名后缀bpmn20.xml是引擎自动识别的规则之一改成别的名字可能部署不进去这是新手常踩的坑。然后是部署和运行// 部署把流程图交给引擎同一份图重复部署会自动升版本号 String deploymentId repositoryService.createDeployment() .name(请假流程-第一版) .addClasspathResource(leave.bpmn20.xml) .deploy() .getId(); // 启动一个流程实例参数是 BPMN 文件里 process 的 id String instanceId runtimeService.startProcessInstanceByKey(leaveProcess).getId(); // 查这个实例当前有没有待办任务 Task task taskService.createTaskQuery() .processInstanceId(instanceId) .singleResult(); System.out.println(当前待办 task.getName() 处理人 task.getAssignee()); // 完成它流程自动流向结束节点 taskService.complete(task.getId()); // 验证流程是否已结束结束的实例在运行时表里查不到 long running runtimeService.createProcessInstanceQuery() .processInstanceId(instanceId) .count(); System.out.println(还在运行的实例数 running); // 期望输出 0createDeployment()是部署入口.addClasspathResource()从类路径读文件.deploy()才真正执行startProcessInstanceByKey()的 key 就是你 BPMN 里写的那个 id不是文件名createTaskQuery()支持按流程实例、按处理人、按流程定义等多种条件过滤这里用实例 id 定位最准complete()是「任务完成」这个动作引擎收到后会按照流程图把执行推进到下一节点。最后那个计数查询很关键它是新手判断「流程到底跑完了没有」最直接的办法运行中的实例数变成 0说明流程走完了如果还是 1说明卡在某个节点上通常是你忘了完成某个任务或者流程图里有节点没连上。3.4 跑完之后回头看刚才那几行代码各干了什么三步跑下来再回头看引擎提供的几个 Service会清晰很多。Service管什么什么时候用RepositoryService流程定义和部署包相当于「模板库」上传流程图、查流程定义列表、挂起某个流程定义RuntimeService运行中的流程实例相当于「正在办的单子」启动流程、传变量、挂起或删除实例TaskService待办任务相当于「某个人手上的活儿」查待办、认领任务、完成任务、加批注HistoryService历史数据相当于「档案室」查已完成的流程、审计谁在什么时候做了什么IdentityService用户和组用户任务里按角色分配时用得上ManagementService引擎自身的管理操作查作业、执行定时任务、看引擎属性这张表不用背用的时候回来查就行。真正要记住的只有一件事所有操作都从这几个 Service 走不要自己去写 SQL 改引擎的表。我见过有人为了「快」直接 update 流程表结果引擎的内部状态和数据库对不上后面查什么问题都是玄学。引擎的 API 虽然啰嗦但它是唯一安全的入口。4. 核心概念拆解流程引擎、BPMN 和那几个躲不开的配置能跑通一个流程之后就该把几个核心概念钉死了。这一章不讲全只讲你前两周一定会碰到的那几个剩下的等遇到再查指南。4.1 ProcessEngine 和那几个 Service先认脸不用背ProcessEngine 是整个引擎的门面一个 Java 应用正常情况下只创建一次创建成本高用完要记得关闭。它的生命周期和你的应用绑定Web 应用里通常在启动时初始化一次之后全局共享。用户指南第 3 章讲的「创建一个 ProcessEngine」和第 4 章讲的「Process Engine API 和服务」其实是一件事的两个视角——前者讲怎么造出来后者讲造出来之后怎么用。有个容易被忽略的点引擎不止一个入口。除了代码里手动buildProcessEngine()还可以通过ProcessEngineConfiguration的配置文件方式activiti.cfg.xml创建或者交给 Spring 的ProcessEngineFactoryBean托管。新手一开始用代码方式最直观等你把项目接进 Spring 了再换成托管方式那时你也能理解为什么要换。Service 的设计思路是「一类事情一个入口」。查询任务就不要去 RuntimeService 里找查询历史就不要去 TaskService 里找。这个边界一旦记住很多「为什么这个方法找不到」的问题会自动消失。4.2 BPMN 2.0那些方框箭头其实就是几种固定元素第一次看 BPMN 图会觉得符号多得离谱。实际拆开看你在入门阶段只需要认识五类东西事件圆圈表示开始、结束、中间发生了什么、任务圆角矩形表示要干的活、网关菱形表示分叉和汇合、顺序流箭头表示往哪走、子流程包含其他元素的框。就这五类剩下的几百页都是它们的排列组合。用户指南第 7 章有个「10 分钟教程」讲的就是这五类元素怎么拼成一个能跑的流程包括画图、XML 表示、启动实例、领取任务、完成任务、结束流程这一整条链路。这一章特别值得先读因为它把一个完整闭环走了一遍你会知道每个符号在代码里对应什么。举个最容易理解的对比userTask是「等某个人来点按钮」serviceTask是「系统自己调一段代码」scriptTask是「跑一段脚本」manualTask是「系统不知道人线下干完了自己说一声」。新手常把它们混着用结果流程卡在那儿没人处理——因为serviceTask不会生成待办它需要你写一个 Java 类去实现具体逻辑。4.3 数据库表名与历史级别一上来就该想清楚的事Activiti6 会在数据库里建几十张表名字都有前缀看懂前缀就够用了act_re_是 repository存流程定义这类「模板」act_ru_是 runtime存正在跑的数据act_hi_是 history存历史档案act_ge_是 general存通用数据比如属性配置。用户指南第 3.7 节专门讲了表名说明第一次看到那张表可能会头皮发麻但记住四个前缀之后大部分表你都能猜出用途。比表名更重要的是历史级别配置。用户指南第 3.12 节和第 11 章都提到了这件事它决定引擎记录多少历史数据。级别从 none 到 full记录的信息越来越多占的空间也越来越大。新手默认配置往往够用但如果你做的系统需要「查三个月前那张单子是谁审的」那就得提前确认历史级别够不够不然等数据积起来了想改历史数据是补不回来的。这就是个典型的后悔药问题配置在项目第一天决定需求在第三个月才提出来。入门阶段不用纠结选哪级但要知道有这么个开关别等出事才发现它存在。4.4 Spring Boot 集成新手最省事的接法如果你的项目是 Spring Boot 的那用户指南第 5.7 节值得优先看。它讲的是自动配置加依赖、配好数据库连接引擎的基本配置就自动完成了不用手写一大堆 bean。同一节里还提到了 REST 支持——引擎自带一套 REST API对应第 13 章前端可以直接调接口查待办、完成任务不用你自己再包一层 Controller。但这里有个新手常见的误区以为 Spring Boot 集成是「零配置」。实际上自动配置只是把默认值填好了数据库连接、历史级别、是否启用异步作业执行器这些关键项还是得你自己按项目情况设。特别是 6.0.0 版本引入的 Job Executor作业执行器它负责跑定时任务和异步任务默认行为和你想象的可能不一样用户指南第 3.9 和 3.10 节专门讲了它怎么激活。入门阶段可以先不碰但要知道「定时边界事件不触发」这类问题八成和它有关。5. 新手最容易翻车的地方五个高频问题排查这一章按「现象 → 原因 → 解决」写。这些都是入门第一周最容易撞上的撞上了别慌先按顺序自查。5.1 环境与依赖类现象一登录页面打不开或者打开是一片空白。原因通常是 war 包没部署成功或者容器的端口被别的程序占了。解决顺序是先看容器日志里有没有 war 解压和部署完成的记录没有就是包放错目录或权限不对再看浏览器地址端口是不是 8080被占用的话换一个最后确认容器启动时用的 JDK 版本是否满足 7 以上版本太低会在启动阶段就报错日志里能看到明确的版本提示别忽略它。现象二加完依赖项目启动报类找不到。原因多半是依赖版本冲突你的项目里已经有别的库引了不同版本的同类组件Maven 按就近原则选了一个结果和引擎要的对不上。解决方式是先跑一次依赖树看引擎相关依赖有没有被顶掉如果被顶掉了就在自己的 pom 里显式声明版本把它钉住。新手常犯的错是「看到报错就再加一个依赖」越加越乱正确做法是先看清报错里缺的是哪个类、属于哪个包。5.2 数据库与配置类现象三昨天跑得好好的流程今天重启后数据全没了。原因是你在用内存数据库 H2而且没配持久化。这在演示环境是设计如此在开发环境就是灾难。解决办法是换成本地文件模式的 H2或者直接连一个 MySQL 之类的正式数据库同时把建表策略从「自动建」调整为「自动更新」避免每次重启都重建表。切换之后记得重新部署一次流程定义因为之前的数据确实找不回来了这是实打实的教训。现象四流程启动了但查不到待办任务。原因通常是三选一任务被分配给了别人assignee写死成了某个用户名而你用另一个账号查、任务有候选人但没认领候选任务不在「我的待办」里得先 claim、或者任务节点压根没生成比如你写的是serviceTask而不是userTask。排查顺序建议反过来先按流程实例 id 查任务列表不带任何处理人条件能查到说明任务生成了问题在分配查不到说明流程没走到那一步回去看流程图有没有断线。注意查任务时不要一上来就叠加处理人条件。先用最宽的条件确认任务存在再逐步收紧这是排查流程问题最省时间的习惯。5.3 流程跑不通时的排查顺序现象五调用完成任务之后流程没往下走也没报错。原因可能是流程图里这个任务后面没有连线或者连线指向的节点定义有误引擎解析时把这条路径忽略了。还有一种情况是流程定义部署了多个版本你启动的是旧版本改的新图根本没生效。解决办法是先查流程定义的版本号确认启动的是最新版再看 BPMN 文件里这个节点的出线是否存在、sourceRef和targetRef是否拼错最后打开引擎的日志级别把 SQL 打出来看它到底执行了什么。排查这类问题有个通用思路永远先确认「引擎认为发生了什么」再确认「你以为发生了什么」。日志里的 SQL 和引擎的查询 API 就是那个「引擎认为」的窗口别靠猜。6. 下一步学什么一份能照着走的进阶路线跑通上面那些之后你已经越过了最陡的那段坡。接下来的路怎么走取决于你要拿它干什么。我给一个大致顺序你可以按项目需要跳着看。阶段该学什么对应指南章节判断学会的标准巩固网关与条件顺序流第 8.3、8.4 节能画出「金额大于 5000 走经理否则走主管」并能跑通巩固变量的传递与作用域第 4.5、4.6 节能在启动时传变量、在任务里读变量、知道全局和局部变量的区别进阶用户任务的各种分配方式第 8.5.1 节能按角色分配、能动态指定处理人、能用监听器改派进阶事件与边界事件第 8.2 节能做出「超过 3 天未审批自动提醒」这种超时逻辑工程化Spring Boot 集成与 REST第 5.7、13 章能把引擎接进真实项目前端直接调接口查待办工程化部署与版本控制第 6 章知道改流程后旧实例会怎样能安全地发新版本深入历史查询与审计第 11 章能查出「这张单子在每个节点停了多久」有几点顺序上的建议。第一网关和变量要一起学因为条件表达式的本质就是读变量分开学两边都学不透。第二用户任务的分配方式优先级很高实际项目里「谁来处理这一步」这个问题出现的频率远超你的想象早学早省事。第三事件和边界事件可以晚一点等你真的遇到「超时提醒」「异常补偿」这类需求再回头翻那时你带着具体问题读效率比通读高好几倍。还有一个我特别想强调的习惯每学一个新元素就在本地最小的那个项目里加一个节点跑一遍别只在文档上看。BPMN 这东西看着简单实际画的时候连线方向、命名、条件表达式的小错误层出不穷跑一次比看十遍管用。我第一次做流程项目时犯过一个很典型的错图改完直接部署到测试环境没在本地验证结果条件表达式的变量名拼错了一个字母流程在生产上走到网关就卡住所有单子堆在那儿一动不动排查了半天才发现是拼写问题。从那以后我每次改完流程图都强制在本地跑一遍完整链路从启动到结束看运行中实例数归零才允许自己部署到下一个环境。这个习惯看起来笨但它救过我很多次。如果你现在还在犹豫要不要开始我的建议是别从文档第一页读起就从那个 war 包丢进容器、用 admin 登进去看一眼开始十分钟的事。看到界面里那张流程图的那一刻你会发现它没那么吓人。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑