graph - 节点的“条件流转”与表达式
2026年1月5日 上午10:12:16
在复杂的业务编排中,流程的走向往往取决于运行时的实时数据。Solon-Flow 的设计哲学是将 业务动作(Node)与流转逻辑(Link) 深度分离。节点只负责完成任务,而连线(Link)则承载了决策的智慧。
本篇将深入源码底层,通过 LinkSpec 的配置探讨如何为流程植入逻辑。
1、核心 API:linkAdd 与 Condition
在 Solon-Flow 的模型中,NodeSpec 通过 linkAdd 方法产生流出方向。每条连线由 LinkSpec 定义,它不仅决定了“下一站去哪”,更通过 when 属性决定了“凭什么去”(Condition)。
条件默认驱动下,支持三种描述方式:
| 条件描述方式 | 示例 |
|---|---|
| Java 脚本描述 | "userId > 12" |
| 容器组件描述 | "@com" |
| Lambda 表达式描述(不能与 yaml / json 互转) | c -> c.<Integer>getAs("risk_level") > 5) |
Java 脚本与容器组件描述示例(可与 yaml / json 互转) :
spec.addActivity("risk_check")
.title("风险校验")
.task("@riskProcessor")
// 满足特定条件走人工审核
.linkAdd("manual_audit", l -> l.when("risk_level > 5")
// 其他情况自动通过
.linkAdd("auto_pass", l -> l.when("@otherwise"));
Lambda 表达式描述示例(不能与 yaml / json 互转) :
spec.addActivity("member_check")
.linkAdd("vip_channel", l -> l.when(ctx -> {
// 利用 Java 语言特性处理复杂逻辑
int score = ctx.get("user_score", 0);
return score > 1000 && "ACTIVE".equals(ctx.get("status"));
}));
2、连接优先级决策机制 (Priority)
当一个节点(主要是排他网关 Exclusive)存在多个流出分支,且多个分支的条件在逻辑上存在重叠时,Solon-Flow 引入了优先级机制。
spec.addExclusive("n1")
// 优先级默认为 0,数值越大越先匹配
.linkAdd("path_A", l -> l.when("...").priority(10))
.linkAdd("path_B", l -> l.when("...").priority(5));
底层逻辑:执行引擎会扫描该节点的所有 LinkSpec,按 priority 降序排列并逐一匹配。在执行排他网关(Exclusive)的策略时,一旦命中首个满足条件的 Link,即停止搜索并发生流转。
3、实战:构建具备“决策能力”的 Graph
结合上述特性,我们可以编码出一个严谨的财务审批流程:
public Graph buildFinancialFlow() {
return Graph.create("fin_audit", "财务审批", spec -> {
return Graph.create("fin_audit", "财务审批", spec -> {
spec.addStart("start").linkAdd("apply");
spec.addActivity("apply").title("申请提交").task("@applyTask").linkAdd("decide");
// 决策中心:根据金额分流
spec.addActivity("decide")
.title("金额校验")
.linkAdd("auto_approve", l -> l.title("小额自动").when("amount <= 200"))
.linkAdd("manager_audit", l -> l.title("经理审核").when("amount <= 5000"))
.linkAdd("boss_audit", l -> l.title("老板特批").when("@otherwise"));
spec.addActivity("auto_approve").task("@autoProc").linkAdd("end");
spec.addActivity("manager_audit").task("@mgrProc").linkAdd("end");
spec.addActivity("boss_audit").task("@bossProc").linkAdd("end");
spec.addEnd("end");
});
}
最佳实践建议
- 上下文一致性:FlowContext 中的变量命名建议采用命名规范(如 biz.amount),避免在大型 Graph 中发生变量污染。
- 解耦判断逻辑:如果 when 里的判断逻辑超过 3 行,建议封装为独立的 ConditionComponent 或在 Context 中预处理结果。
4、结语
掌握了 LinkSpec 的 when 配置,您便掌握了流程的“指挥权”。在 Solon-Flow 的世界里,Graph 不再是静态的线条,而是能够随数据起舞的动态逻辑网。
在下一篇 《动态图生成与运行时变更》 中,我们将探索如何在应用不重启的情况下,利用 GraphSpec.copy 动态地重构这张逻辑图。