在复杂的业务编排中，流程的走向往往取决于运行时的实时数据。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 互转） ：

```java
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 互转） ：

```java
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 引入了优先级机制。


```java
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

结合上述特性，我们可以编码出一个严谨的财务审批流程：

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

