Solon v3.8.0

graph - 节点的“条件流转”与表达式

</> markdown
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 动态地重构这张逻辑图。