1.什么是跳过表达式?
跳过表达式(Skip Expression) 是 Flowable 提供的一种机制,它允许你在流程执行到某个活动(如用户任务、服务任务等)时,通过一个表达式来动态决定是否要“跳过”这个活动。
简单来说,你在一个任务上配置一个表达式。在流程准备执行这个任务之前,Flowable 会先计算这个表达式的值:
如果表达式的计算结果为 true,那么这个任务就会被自动跳过,流程直接沿着后续的路径继续执行,就好像这个任务已经瞬间完成了一样。
如果表达式的计算结果为 false(或表达式不存在、无效),那么这个任务就会被正常创建和执行(例如,生成一个待办任务给用户)。
这个表达式的语法通常是 JUEL (Java Unified Expression Language),并且可以访问所有当前的流程变量。
2. 为什么需要它?(解决了什么问题)
如果没有跳过表达式,当我们需要根据条件决定是否执行一个任务时,通常需要在流程图上画一个排他网关(Exclusive Gateway),像这样:
A[开始] --> B{需要经理审批吗?};
B – 是 --> C[经理审批];
B – 否 --> D[结束];
C --> D;
种方式完全可行,但当流程变得复杂,充满了各种可选步骤时,流程图上会布满大量的网关和连线,显得非常杂乱,可读性下降。
使用跳过表达式的优势:
简化流程图:你可以将判断逻辑直接内嵌到任务节点中,而不需要额外的网关。这让主干流程看起来更清晰、更线性。
提高灵活性:流程的行为可以完全由流程变量驱动,使得流程能够适应更多变的业务场景。
减少模型维护成本:当业务逻辑(例如,跳过的条件)发生变化时,你可能只需要修改任务的属性,而不需要重新绘制流程图的结构。
使用跳过表达式后的流程图可能看起来是这样的:
A[开始] --> C[经理审批 (如果金额>5000)];
C --> D[结束];
这里的判断逻辑 如果金额>5000 就被隐藏在了“经理审批”任务的属性里。
3. 如何配置和使用?
跳过表达式是 BPMN 2.0 规范中 Flowable 的一个扩展属性,其 XML 属性名为 flowable:skipExpression。
你可以在 BPMN 文件的 或其他任务节点上直接添加这个属性。
示例:一个请假审批流程
假设我们有一个规则:如果请假天数小于等于 1 天,则不需要部门经理审批,直接通过。
<definitions ... xmlns:flowable="http://flowable.org/bpmn">
...
<process id="leaveProcess" name="请假流程">
<startEvent id="start"/>
<sequenceFlow sourceRef="start" targetRef="submitLeave"/>
<userTask id="submitLeave" name="填写请假单"/>
<sequenceFlow sourceRef="submitLeave" targetRef="managerApproval"/>
<!-- 部门经理审批任务 -->
<userTask id="managerApproval" name="部门经理审批"
flowable:assignee="manager"
flowable:skipExpression="${leaveDays <= 1}"> <!-- 核心在这里! -->
</userTask>
<sequenceFlow sourceRef="managerApproval" targetRef="end"/>
<endEvent id="end"/>
</process>
</definitions>
工作流程:
流程启动后,用户在“填写请假单”任务中提交表单,并设置了一个流程变量 leaveDays。
当流程流转到“部门经理审批”任务时,Flowable 引擎会检查 flowable:skipExpression。
它会获取 leaveDays 这个流程变量的值,并计算 ${leaveDays <= 1}。
如果用户请假 0.5 天,leaveDays 为 0.5,表达式结果为 true。于是,managerApproval 任务被跳过,流程直接到达结束节点。
如果用户请假 3 天,leaveDays 为 3,表达式结果为 false。于是,一个名为“部门经理审批”的待办任务会被创建并分配给 manager。
4. 实际应用场景
审批流程:金额小于某个阈值时,跳过高级别审批。
入职流程:如果是内部转岗员工,跳过“新人培训”、“办公用品领取”等步骤。
订单处理:如果是VIP客户,跳过“信用审核”步骤。
数据处理:如果前一个服务任务已经成功校验了数据(并设置了如 dataValid=true 的变量),则跳过后续的“人工数据复核”任务。
5. 注意事项
变量必须存在:表达式中引用的流程变量(如 leaveDays)必须在流程执行到该任务之前就已经被设置。否则,表达式求值时可能会因为找不到变量而报错。一个好的实践是在启动流程或在之前的任务中确保变量被初始化。
表达式的清晰性:虽然跳过表达式简化了图表,但也把逻辑“隐藏”了起来。如果跳过逻辑非常复杂,包含多个 AND 和 OR,那么使用一个排他网关可能会让逻辑更清晰,更易于理解和维护。需要在这两者之间做好权衡。
布尔值变量:一个常见的用法是使用一个布尔型的流程变量来控制,例如 ${skipManagerApproval}。这样,业务逻辑可以在之前的脚本任务或服务任务中计算好,然后把结果(true 或 false)存入这个变量,使得跳过表达式本身非常简洁。