第1章:工作流引擎核心概念
大家好,我是你们的老朋友。今天咱们正式开始聊工作流引擎。
说实话,我第一次接触工作流引擎时,脑子里全是问号。这东西到底在干什么?为什么要有它?后来做了几个项目,踩了不少坑,才慢慢摸清楚门道。
这一章,我会把工作流引擎最核心的几个概念讲透。你理解透了,后面学起来就轻松了。
1.1 流程定义
流程定义是什么?说白了,就是一张「蓝图」。
你想想看,一个请假流程,需要经过哪些步骤?员工提交申请 -> 直属领导审批 -> 部门经理审批 -> 人事备案。这个步骤顺序,就是流程定义。
我在项目中遇到过一种情况:客户说「我们的审批流程很简单,就三步」。结果一调研,发现每个部门的三步都不一样,有的还要加会签、加条件分支。嗯,流程定义就是用来描述这些「不一样」的。
一个典型的流程定义包含以下要素:
- 节点(Node):流程中的每个步骤,比如「提交申请」节点、「领导审批」节点
- 连线(Sequence Flow):节点之间的流转方向
- 网关(Gateway):用来做分支判断,比如金额大于5000需要总经理审批
- 事件(Event):流程开始、结束、超时等触发点
重点记住:流程定义是「静态的」,它就像一张地图,画好了就不动了。
1.2 流程实例
流程实例,就是「跑起来」的流程定义。
举个例子:你定义了请假流程的蓝图。张三今天请假,系统就为他创建一个流程实例。李四明天请假,系统再创建一个新的流程实例。
每个流程实例都是独立的。张三的请假流程卡在领导审批环节,不影响李四的流程走到人事备案。
我个人习惯用「订单号」来理解流程实例。你想想看,电商系统里每个订单都是独立的,有自己的状态、创建时间、处理人。流程实例也一样,它有自己的:
- 实例ID:唯一标识
- 当前节点:流程走到哪一步了
- 变量数据:比如请假天数、审批意见
- 状态:运行中、已完成、已终止
小技巧:调试时,我习惯把流程实例ID打印到日志里。这样出问题了,直接搜ID就能定位到具体流程,省时省力。
1.3 任务节点
任务节点,是流程实例中的「动作单元」。
流程定义里的每个步骤,最终都会变成一个任务节点。比如「领导审批」这个步骤,在流程实例里就是一个待办任务。
任务节点分几种类型:
| 类型 | 说明 | 例子 |
|---|---|---|
| 用户任务 | 需要人来操作 | 审批、填写表单 |
| 服务任务 | 系统自动执行 | 发送邮件、调用API |
| 脚本任务 | 执行一段脚本 | 计算金额、校验数据 |
| 子流程 | 嵌套另一个流程 | 采购流程里嵌套付款流程 |
我曾经犯过一个错:把所有任务都设计成用户任务。结果一个流程跑下来,需要人工点十几次。后来改成服务任务自动处理中间环节,效率提升了好几倍。
1.4 流转条件
流转条件,就是「什么时候走这条路」。
没有条件的流程,就像一条直线,从起点走到终点。但现实中的流程往往有分支:
- 请假天数 ≤ 3天,部门经理审批即可
- 请假天数 > 3天,需要总经理审批
这个「≤ 3天」和「> 3天」,就是流转条件。
在代码里,流转条件通常写成表达式:
// 伪代码示例
if (leaveDays <= 3) {
goTo("部门经理审批");
} else {
goTo("总经理审批");
}
注意:流转条件一定要考虑边界情况。我曾经遇到过「等于3天」时两个分支都走不通的bug,就是因为条件写成了 < 3 和 > 3,漏掉了 = 3 的情况。
1.5 工作流引擎架构
聊完概念,咱们看看工作流引擎的整体架构。
我习惯把工作流引擎分成三层:
- 定义层:负责流程定义的解析、校验、存储
- 运行时层:负责流程实例的创建、推进、状态管理
- 交互层:负责待办任务、表单展示、操作入口
这三层的关系,你可以这样理解:
- 定义层是「图纸」
- 运行时层是「施工队」
- 交互层是「现场指挥」
图纸画好了,施工队按图纸干活,现场指挥协调各方。缺一不可。
一个简化的工作流引擎核心流程如下:
// 核心流程伪代码
public class WorkflowEngine {
// 1. 解析流程定义
public ProcessDefinition parseDefinition(String bpmnXml) {
// 解析BPMN文件,构建节点和连线
}
// 2. 启动流程实例
public ProcessInstance startProcess(String defId, Map<String, Object> variables) {
// 根据定义创建实例,设置初始变量
}
// 3. 推进流程
public void completeTask(String taskId, Map<String, Object> result) {
// 完成任务,计算下一个节点
// 检查流转条件,决定走哪条分支
}
}
嗯,这里要注意:实际引擎比这个复杂得多。要考虑并发、事务、持久化、历史记录等等。但核心骨架就是这三步。
小结
这一章我们讲了五个核心概念:
- 流程定义:静态蓝图
- 流程实例:运行中的流程
- 任务节点:流程中的动作单元
- 流转条件:分支判断逻辑
- 引擎架构:定义层、运行时层、交互层
你把这些概念搞清楚了,后面学具体实现时就不会晕。下一章,咱们开始动手搭建一个最小可用的工作流引擎。
一句话总结:流程定义是「画」出来的,流程实例是「跑」出来的,任务节点是「做」出来的,流转条件是「判」出来的。