Solon Flow 实战:用 50 行 YAML 实现一个请假审批流(含中断恢复、并行网关、条件分支)

一、为什么需要流程编排?

做后台开发的同学一定遇到过这类需求:

  • 请假审批:员工提交 -> 主管审批 -> 部门经理审批 -> 副总审批,但不同天数的审批链路还不一样
  • 合同审批:金额超过 10 万需要额外部门会签,超过 50 万需要财务参与
  • 数据抓取:多线程并行爬取多个数据源,再汇总处理

这类需求本质上都是一个 有向图 的流转问题。如果全靠 if-else 硬编码,代码很快就会变成面条式意大利粉。

Solon Flow 是 Solon 生态中的通用流程编排框架,它的核心思路是:用 YAML(或 Java Fluent API)描述流转逻辑,用引擎驱动执行。不需要重依赖、不需要外部数据库、不需要部署服务,一个 jar 包就能跑。

今天这篇文章,我们用最经典的"请假审批流"作为实战案例,从零到一跑通 Solon Flow 的核心能力。

二、5 分钟跑起来:Hello World

2.1 添加依赖

pom.xml 中添加:

xml 复制代码
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-flow</artifactId>
</dependency>

不需要额外数据库、不需要消息中间件,一个依赖搞定。

2.2 创建流程定义文件

resources/flow/ 目录下创建 demo1.yml

yaml 复制代码
id: "demo1"
layout:
  - { id: "s", type: "start", link: "n1" }
  - { id: "n1", type: "activity", task: 'System.out.println("hello world!");', link: "e" }
  - { id: "e", type: "end" }

这是一个最简单的三节点流程:开始 -> 执行打印 -> 结束。

2.3 执行

两种方式,任选其一:

方式一:原生 Java 模式(不需要启动 Solon 容器)

java 复制代码
import org.noear.solon.flow.FlowEngine;

public class Demo {
    public static void main(String[] args) {
        FlowEngine engine = FlowEngine.newInstance();
        engine.load("classpath:flow/*");

        engine.eval("demo1");
        // 控制台输出:hello world!
    }
}

方式二:Solon 容器注解模式

先在应用配置中声明流程文件位置:

yaml 复制代码
# application.yml
solon.flow:
  - "classpath:flow/*.yml"

然后在组件中注入引擎直接使用:

java 复制代码
@Component
public class DemoCom implements LifecycleBean {
    @Inject
    private FlowEngine flowEngine;

    @Override
    public void start() throws Throwable {
        flowEngine.eval("demo1");
    }
}

运行后控制台输出:hello world!。5 分钟,一个流程就跑通了。

三、核心概念速览:7 种节点 + 引擎 + 上下文

在进入实战之前,先过一遍 Solon Flow 的核心概念。这些概念非常精简,但足够覆盖绝大多数编排场景。

3.1 七种节点类型

Solon Flow 的图由 7 种节点 构成:

节点类型 说明 执行任务 连接条件 多线程 可流入 可流出
start 开始节点 - - - 0 1
activity 活动节点(缺省类型) 支持 - - 1...n 1...n
exclusive 排他网关(单选) 支持 支持 - 1...n 1...n
inclusive 包容网关(多选) 支持 支持 - 1...n 1...n
parallel 并行网关(全选) 支持 - 支持 1...n 1...n
loop 循环网关 支持 - - 1 1
end 结束节点 - - - 1...n 0

几个关键点:

  • startend 每个图必须有且仅有一个
  • exclusive(排他网关):相当于"单选",只有一条满足条件的连接会流出,没有匹配的用默认(无条件)连接
  • inclusive(包容网关):相当于"多选",所有满足条件的连接都会流出,需要成对使用实现汇聚
  • parallel(并行网关):相当于"全选",所有连接都会流出,内部使用多线程执行,需要成对使用实现汇聚
  • loop (循环网关):遍历集合并循环流出,通过 $for$in 元数据指定变量

3.2 流程引擎(FlowEngine)

FlowEngine 是执行流程的核心入口,主要负责:

  • 加载和解析流程定义(支持 YAML、JSON、Java 硬编码)
  • 驱动流程执行
  • 管理拦截器链
java 复制代码
FlowEngine engine = FlowEngine.newInstance();
engine.load("classpath:flow/*.yml");     // 加载
engine.eval("demo1");                     // 执行(按 id 匹配)
engine.eval("demo1", context);            // 执行(带上下文)
engine.eval("demo1", 1, context);         // 执行(深度控制,单步调试)

3.3 上下文(FlowContext)

FlowContext 是流程执行的核心现场,承载了业务数据、控制状态和执行轨迹:

java 复制代码
// 创建
FlowContext context = FlowContext.of();
FlowContext context = FlowContext.of("instance-001");

// 传递业务参数
context.put("day", 5);
context.put("applicant", "张三");

// 获取参数
int day = context.getAs("day");

// 控制流程
context.stop();       // 停止(可用于中断恢复)
context.interrupt();  // 中断当前分支

// 序列化与恢复
String snapshot = context.toJson();
FlowContext restored = FlowContext.fromJson(snapshot);

// 执行轨迹
context.lastNodeId();  // 最后执行的节点 ID
context.trace();       // 完整执行轨迹

概念不多,但覆盖了编排、执行、控制、恢复四大核心能力。下面进入实战。

四、实战一:50 行 YAML 实现请假审批流(条件分支 exclusive)

4.1 业务规则

一个请假审批的流转规则如下:

复制代码
员工发起请假
  -> 主管审批
    -> 天数 < 3天:直接结束(主管批了就行)
    -> 天数 >= 3天:部门经理审批
      -> 天数 < 7天:结束
      -> 天数 >= 7天:副总审批 -> 结束

这是一个典型的 条件分支 场景,用 exclusive(排他网关)来实现。

4.2 流程定义

创建 resources/flow/leave-approval.yml

yaml 复制代码
id: "leave-approval"
title: "请假审批"
layout:
  - { id: "s", type: "start", title: "发起人", meta: { role: "employee" }, link: "n1" }
  - { id: "n1", type: "activity", title: "主管审批", task: "@tl_approve", link: "g1" }
  - { id: "g1", type: "exclusive", title: "天数判断", link: [
      { nextId: "e", title: "3天以下" },
      { nextId: "n2", title: "3天以上", when: "day>=3" }
    ]}
  - { id: "n2", type: "activity", title: "部门经理审批", task: "@dm_approve", link: "g2" }
  - { id: "g2", type: "exclusive", title: "天数判断", link: [
      { nextId: "e", title: "7天以下" },
      { nextId: "n3", title: "7天以上", when: "day>=7" }
    ]}
  - { id: "n3", type: "activity", title: "副总审批", task: "@vp_approve", link: "e" }
  - { id: "e", type: "end" }

一共 8 个节点(含 start 和 end),YAML 共 50 行以内

解释几个关键点:

  • task: "@tl_approve":以 @ 开头的是任务组件引用,对应 Java 中注册的 TaskComponent
  • when: "day>=3":连接条件表达式,引擎通过表达式引擎(SnEL)求值,day 从上下文中获取
  • 排他网关 g1:如果 day>=3 满足,走 n2;否则走默认连接 e(没有 when 的连接就是默认)
  • meta: { role: "employee" }:元数据,可以在拦截器或任务中读取,用于权限判断等

4.3 任务组件实现

每个 task 中的 @xxx 引用,对应一个 Java 组件:

java 复制代码
import org.noear.solon.flow.core.TaskComponent;
import org.noear.solon.flow.core.FlowContext;
import org.noear.solon.flow.core.Node;

// 主管审批
@Component("tl_approve")
public class TeamLeaderApprove implements TaskComponent {
    @Override
    public void run(FlowContext context, Node node) throws Throwable {
        String applicant = context.getAs("applicant");
        int day = context.getAs("day");
        System.out.println("主管审批通过:申请人=" + applicant + ", 天数=" + day);
        context.put("tl_approved", true);
    }
}

// 部门经理审批
@Component("dm_approve")
public class DeptManagerApprove implements TaskComponent {
    @Override
    public void run(FlowContext context, Node node) throws Throwable {
        String applicant = context.getAs("applicant");
        System.out.println("部门经理审批通过:申请人=" + applicant);
        context.put("dm_approved", true);
    }
}

// 副总审批
@Component("vp_approve")
public class VPApprove implements TaskComponent {
    @Override
    public void run(FlowContext context, Node node) throws Throwable {
        String applicant = context.getAs("applicant");
        System.out.println("副总审批通过:申请人=" + applicant);
        context.put("vp_approved", true);
    }
}

4.4 测试运行

java 复制代码
public class LeaveApprovalTest {
    public static void main(String[] args) {
        FlowEngine engine = FlowEngine.newInstance();
        engine.load("classpath:flow/leave-approval.yml");

        // 场景1:请假2天 -> 主管审批 -> 结束
        FlowContext ctx1 = FlowContext.of()
                .put("applicant", "张三")
                .put("day", 2);
        engine.eval("leave-approval", ctx1);
        // 输出:主管审批通过:申请人=张三, 天数=2

        // 场景2:请假5天 -> 主管 -> 部门经理 -> 结束
        FlowContext ctx2 = FlowContext.of()
                .put("applicant", "李四")
                .put("day", 5);
        engine.eval("leave-approval", ctx2);
        // 输出:主管审批通过... 部门经理审批通过...

        // 场景3:请假10天 -> 主管 -> 部门经理 -> 副总 -> 结束
        FlowContext ctx3 = FlowContext.of()
                .put("applicant", "王五")
                .put("day", 10);
        engine.eval("leave-approval", ctx3);
        // 输出:主管审批通过... 部门经理审批通过... 副总审批通过...
    }
}

这就是完整的请假审批流。50 行 YAML + 几个任务组件,流转逻辑一目了然。

五、实战二:并行网关 --- 同时发送短信和邮件通知

审批通过后,需要同时给申请人和 HR 发送短信通知和邮件通知。这是一个典型的 并行执行 场景,用 parallel(并行网关)来实现。

yaml 复制代码
id: "notify-flow"
title: "审批通知"
layout:
  - { id: "s", type: "start", link: "n1" }
  - { id: "n1", type: "activity", title: "审批完成", task: "@after_approve", link: "g1" }
  - { id: "g1", type: "parallel", title: "并行发送", link: ["n2", "n3"] }
  - { id: "n2", type: "activity", title: "发送短信", task: "@send_sms", link: "g2" }
  - { id: "n3", type: "activity", title: "发送邮件", task: "@send_email", link: "g2" }
  - { id: "g2", type: "parallel", title: "汇聚结果", link: "e" }
  - { id: "e", type: "end" }

关键说明:

  • g1 是并行网关的 分叉端:所有流出连接都会同时执行(多线程)
  • g2 是并行网关的 汇聚端:等待所有流入连接到齐后,才继续往后流转
  • parallel 必须成对使用(分叉 + 汇聚)

任务组件:

java 复制代码
@Component("send_sms")
public class SendSms implements TaskComponent {
    @Override
    public void run(FlowContext context, Node node) throws Throwable {
        String applicant = context.getAs("applicant");
        System.out.println("[短信] 通知 " + applicant + ":您的请假申请已审批通过");
    }
}

@Component("send_email")
public class SendEmail implements TaskComponent {
    @Override
    public void run(FlowContext context, Node node) throws Throwable {
        String applicant = context.getAs("applicant");
        System.out.println("[邮件] 通知 " + applicant + ":您的请假申请已审批通过");
    }
}

运行后,短信和邮件两个任务会 并行执行 (parallel 节点内部使用多线程),执行完毕后在 g2 汇聚,然后继续往后。

六、实战三:中断与恢复 --- 审批到一半要等领导出差回来

实际业务中,审批往往不是一次完成的。比如副总出差了,流程要暂停,等副总回来再继续。这就是 Solon Flow 的 中断与恢复 能力。

6.1 核心机制

  • 在任务组件中调用 context.stop(),流程会停在当前节点
  • 通过 context.toJson() 将整个上下文序列化为 JSON 快照
  • 需要恢复时,通过 FlowContext.fromJson() 还原上下文
  • 再次调用 engine.eval(),引擎会 自动从上次停止的节点继续执行

6.2 修改副总审批组件,加入中断逻辑

java 复制代码
@Component("vp_approve")
public class VPApprove implements TaskComponent {
    @Override
    public void run(FlowContext context, Node node) throws Throwable {
        String applicant = context.getAs("applicant");
        boolean vpAvailable = context.getAs("vpAvailable"); // 副总是否在岗

        if (!vpAvailable) {
            System.out.println("副总出差中,流程暂停等待。申请人=" + applicant);
            context.stop(); // 中断流程
            return;
        }

        System.out.println("副总审批通过:申请人=" + applicant);
        context.put("vp_approved", true);
    }
}

6.3 执行与恢复

java 复制代码
public class InterruptResumeTest {
    public static void main(String[] args) {
        FlowEngine engine = FlowEngine.newInstance();
        engine.load("classpath:flow/leave-approval.yml");

        // ===== 第一阶段:提交请假,副总出差,流程暂停 =====
        FlowContext context = FlowContext.of("leave-001")
                .put("applicant", "王五")
                .put("day", 10)
                .put("vpAvailable", false);  // 副总不在

        engine.eval("leave-approval", context);
        // 输出:主管审批通过... 部门经理审批通过... 副总出差中,流程暂停等待

        System.out.println("流程是否已停止: " + context.isStopped());  // true
        System.out.println("最后执行节点: " + context.lastNodeId());    // n3

        // 持久化快照到数据库(实际项目中)
        String snapshot = context.toJson();
        // db.save("leave-001", snapshot);

        // ===== 第二阶段:副总回来了,恢复流程 =====
        // 从数据库加载快照
        // String snapshot = db.load("leave-001");
        FlowContext restored = FlowContext.fromJson(snapshot);
        restored.put("vpAvailable", true);  // 更新状态:副总回来了

        engine.eval("leave-approval", restored);
        // 输出:副总审批通过:申请人=王五
    }
}

这个能力非常强大。上下文的序列化和恢复是 快照级别 的,意味着:

  • 可以跨线程恢复(异步回调场景)
  • 可以跨时间恢复(长流程场景)
  • 可以跨服务器恢复(分布式场景,配合数据库持久化快照)

非常适合审批流、AI 对话流等长流程场景。

七、实战四:循环遍历 --- 批量审批

假设部门经理需要一次性审批团队所有待处理的请假单,可以用 loop(循环网关) 实现:

yaml 复制代码
id: "batch-approve"
title: "批量审批"
layout:
  - { id: "s", type: "start", link: "g1" }
  - { id: "g1", type: "loop", meta: { "$for": "item", "$in": "pendingList" }, link: "n1" }
  - { id: "n1", type: "activity", title: "逐条审批", task: "@batch_item_approve", link: "g2" }
  - { id: "g2", type: "loop", link: "e" }
  - { id: "e", type: "end" }

关键说明:

  • 第一个 loop 节点 g1 是循环的 流出端 :通过 $in 从上下文中获取集合 pendingList,用 $for 声明循环变量名 item
  • 循环每取出一个元素,推入上下文变量 item,后续节点可直接使用
  • 第二个 loop 节点 g2 是循环的 汇聚端:等待遍历结束后才往后流转
  • loop 必须成对使用

任务组件:

java 复制代码
@Component("batch_item_approve")
public class BatchItemApprove implements TaskComponent {
    @Override
    public void run(FlowContext context, Node node) throws Throwable {
        // 每次循环,item 变量自动推入上下文
        Map<String, Object> item = context.getAs("item");
        System.out.println("批量审批处理:" + item.get("applicant") + " - " + item.get("day") + "天");
    }
}

执行:

java 复制代码
FlowContext context = FlowContext.of()
        .put("pendingList", Arrays.asList(
            Map.of("applicant", "张三", "day", 1),
            Map.of("applicant", "李四", "day", 4),
            Map.of("applicant", "王五", "day", 8)
        ));
engine.eval("batch-approve", context);
// 输出:
// 批量审批处理:张三 - 1天
// 批量审批处理:李四 - 4天
// 批量审批处理:王五 - 8天

八、实战五:Graph 编码模式 --- 用 Java Fluent API 定义流程

除了 YAML,Solon Flow 还支持用纯 Java 代码定义流程。这在需要动态构建流程、或者流程需要根据参数动态调整的场景下非常有用。

java 复制代码
import org.noear.solon.flow.core.Graph;

Graph graph = Graph.create("leave", spec -> {
    spec.addStart("s").title("发起人").linkAdd("n1");

    spec.addActivity("n1").title("主管审批").task("@tl_approve").linkAdd("g1");

    spec.addExclusive("g1")
            .linkAdd("e", l -> l.title("3天以下"))
            .linkAdd("n2", l -> l.title("3天以上").when("day>=3"));

    spec.addActivity("n2").title("部门经理审批").task("@dm_approve").linkAdd("g2");

    spec.addExclusive("g2")
            .linkAdd("e", l -> l.title("7天以下"))
            .linkAdd("n3", l -> l.title("7天以上").when("day>=7"));

    spec.addActivity("n3").title("副总审批").task("@vp_approve").linkAdd("e");

    spec.addEnd("e");
});

// 直接执行
FlowEngine engine = FlowEngine.newInstance();
engine.eval(graph);

Fluent API 的方法名与 YAML 中的节点类型完全对应:

  • spec.addStart(id) / spec.addEnd(id) / spec.addActivity(id) / spec.addExclusive(id) ...
  • .title() 设置标题
  • .task() 设置任务
  • .linkAdd(nextId) 添加流出连接(无参 lambda 可设置连接标题和条件)
  • .when() 设置连接条件表达式

此外,Graph 还支持复制和修改已有图:

java 复制代码
// 复制并修改为新图
Graph graphNew = Graph.copy(graph, spec -> {
    spec.removeNode("n3");  // 移除副总审批节点
    spec.getNode("n2").linkRemove("n3").linkAdd("e"); // n2 直接连到 end
});

这种能力非常适合做 流程模板:先定义基础流程,再根据租户/业务线动态裁剪。

两种模式也可以互相转换:

java 复制代码
// Graph -> YAML(反向序列化)
String yaml = graph.toYaml();

// Graph -> JSON
String json = graph.toJson();

// Graph -> PlantUML 状态图文本(v3.9.5+)
String plantuml = graph.toPlantuml();

九、高级能力:拦截器、事件总线、单步调试

9.1 拦截器(AOP 能力)

Solon Flow 提供了 FlowInterceptor 拦截器接口,可以在不修改流程定义和任务组件的前提下,对流程执行进行切面增强。

常见的使用场景:

场景 实现方式
性能监控 doIntercept 中统计总耗时
执行审计 onNodeStart 记录节点 ID 和上下文参数
安全校验 doIntercept 中校验必要 Token
参数补全 流程开始前向上下文注入全局配置
java 复制代码
@Component
public class FlowAuditInterceptor implements FlowInterceptor {
    static Logger log = LoggerFactory.getLogger(FlowAuditInterceptor.class);

    @Override
    public void doIntercept(FlowInvocation inv) throws Throwable {
        long start = System.currentTimeMillis();
        try {
            inv.invoke();  // 执行流程
        } catch (Throwable ex) {
            log.error("流程执行异常: " + inv.getStartNode().getGraph().getId(), ex);
            throw ex;
        } finally {
            long elapsed = System.currentTimeMillis() - start;
            log.info("流程 {} 执行耗时: {}ms", inv.getStartNode().getGraph().getId(), elapsed);
        }
    }

    @Override
    public void onNodeStart(FlowContext context, Node node) {
        log.info("节点开始: id={}, title={}", node.getId(), node.getTitle());
    }

    @Override
    public void onNodeEnd(FlowContext context, Node node) {
        log.info("节点完成: id={}, title={}", node.getId(), node.getTitle());
    }
}

拦截器可以通过 Solon 容器自动注册(@Component),也可以手动注册:

java 复制代码
engine.addInterceptor(new FlowAuditInterceptor());

9.2 事件总线(解耦利器)

Solon Flow 内置了基于 DamiBus 的事件总线,支持在流程执行中进行 上下文级别(实例级别) 的事件通信。

三种模式:

模式 方法 说明
发送 send 异步/同步广播,不要求答复
请求 call 发送并等待答复(类似 RPC)
stream 发送并持续接收数据流

在流程中触发事件:

java 复制代码
@Component("notify_task")
public class NotifyTask implements TaskComponent {
    @Override
    public void run(FlowContext context, Node node) throws Throwable {
        // 发送事件(广播)
        context.eventBus().send("leave.approved", context.getAs("applicant"));
    }
}

在外部订阅事件:

java 复制代码
FlowContext context = FlowContext.of();
context.eventBus().<String>listen("leave.approved", event -> {
    System.out.println("收到审批通过通知: " + event.getPayload());
    // 在这里处理:发企微通知、更新统计报表、推送消息队列等
});

engine.eval("leave-approval", context);

通过事件总线,流程定义只管"发信号",具体的业务处理(发通知、写日志、更新缓存)由外部监听器处理,实现了极度解耦。

9.3 单步前进(调试模式)

Solon Flow 支持深度控制,可以逐步执行流程中的每一个节点,类似调试器的单步执行:

java 复制代码
FlowEngine engine = FlowEngine.newInstance();
engine.load("classpath:flow/leave-approval.yml");

FlowContext context = FlowContext.of()
        .put("applicant", "张三")
        .put("day", 2);

// 每次执行一步(深度=1)
engine.eval("leave-approval", 1, context);
System.out.println("当前节点: " + context.lastRecord().getTitle()); // 发起人

engine.eval("leave-approval", 1, context);
System.out.println("当前节点: " + context.lastRecord().getTitle()); // 主管审批

engine.eval("leave-approval", 1, context);
System.out.println("当前节点: " + context.lastRecord().getTitle()); // 天数判断

这个能力非常适合:

  • 流程调试:开发阶段逐步排查问题
  • 流程演示:向产品/业务逐步展示流转过程
  • 交互式流程:每个节点执行后等待用户确认再继续

十、可视化设计器

对于不熟悉 YAML 的业务人员,Solon Flow 提供了 可视化设计器,可以通过拖拽的方式设计流程图,然后导出为 YAML/JSON。

设计器特点:

  • 拖拽式节点编排,所见即所得
  • 支持 7 种节点类型的可视化配置
  • 可设置节点属性(标题、任务、条件、元数据等)
  • 导出为 YAML/JSON/Map 格式,与代码模式无缝衔接

有了设计器,流程定义可以由业务人员直接参与维护,开发人员只需要关注任务组件的实现,实现真正的职责分离。

十一、包容网关补充 --- 条件会签场景

除了排他网关(单选)和并行网关(全选),还有一种 包容网关(inclusive),相当于"多选"------满足条件的连接都会流出。

以合同审批为例,金额不同需要不同部门会签:

yaml 复制代码
id: "contract-approval"
title: "合同审批(条件会签)"
layout:
  - { id: "s", type: "start", title: "发起人", meta: { role: "employee" }, link: "n1" }
  - { id: "n1", type: "activity", title: "主管批", meta: { role: "tl" }, link: "g1" }
  - { id: "g1", type: "inclusive", title: "会签", link: [
      { nextId: "n2", title: "10万以上", when: "amount>=100000" },
      { nextId: "n3", title: "50万以上", when: "amount>=500000" },
      { nextId: "n4", title: "90万以上", when: "amount>=900000" }
    ]}
  - { id: "n2", type: "activity", title: "本部门经理批", task: "@dm_approve", link: "g2" }
  - { id: "n3", type: "activity", title: "生产部经理批", task: "@prod_approve", link: "g2" }
  - { id: "n4", type: "activity", title: "财务部经理批", task: "@fin_approve", link: "g2" }
  - { id: "g2", type: "inclusive", link: "e" }
  - { id: "e", type: "end" }

如果合同金额 80 万,则 g1 会同时流出 n2(10万以上)和 n3(50万以上),两个部门并行会签。g2 作为汇聚端,等待所有满足条件的流入到齐后才继续。

十二、总结与进阶

12.1 本文覆盖的核心能力

能力 对应特性 实战章节
条件分支 exclusive 排他网关 实战一:请假审批
并行执行 parallel 并行网关 实战二:并行通知
中断恢复 context.stop() + toJson/fromJson 实战三:中断恢复
循环遍历 loop 循环节点 + f o r / for/ for/in 实战四:批量审批
Fluent API Graph.create() 硬编码 实战五:Graph 编码
条件会签 inclusive 包容网关 十一章:合同审批
AOP 扩展 FlowInterceptor 拦截器 高级能力
事件解耦 DamiBus 事件总线 高级能力
单步调试 eval(id, depth, context) 高级能力
可视化设计 可视化设计器 第十章

12.2 Solon Flow 的适用场景

  • 无状态流:计算编排、规则决策、数据抓取、AI Agent 工具调用链
  • 有状态流:审批流、长流程、需要中断恢复的业务场景
  • 混合场景:审批流 + 自动化任务编排的混合流程

12.3 进阶方向

如果你已经在项目中使用 Solon Flow,还可以关注以下进阶主题:

  • solon-flow-workflow:在 solon-flow 基础上封装了工作流服务,提供任务认领(claimTask)、任务查找(findTask)、状态控制(StateController)、状态持久化(StateRepository)等开箱即用的工作流能力
  • 引擎驱动定制 :通过自定义 FlowDriver 实现不同的执行策略
  • 元数据扩展 :通过 meta 字段实现节点级别的自定义扩展(权限、超时、重试等)
  • Solon AI Flow:将 Solon Flow 与 AI 能力结合,实现 ReAct Agent、AI 工具链等场景
  • PlantUML 导出 :通过 graph.toPlantuml() 生成状态图文档,方便技术评审

12.4 项目信息


写在最后:流程编排的本质是"把流转逻辑从业务代码中抽离出来"。Solon Flow 用最轻量的方式做到了这一点------一个依赖、一个 YAML 文件、几行 Java 代码,就能跑起一个完整的审批流。如果你正在寻找一个轻量、灵活、不绑定外部服务的流程编排方案,值得试试。

相关推荐
iiiiyu4 小时前
面向对象和集合编程题
java·开发语言·前端·数据结构·算法·编程语言
taocarts_bidfans4 小时前
2026跨境SaaS工具选型指南:Taoify与Shopify/Shopyy/Ueeshop深度对比
java·前端·javascript·跨境电商·独立站
Tigshop开源商城4 小时前
『切换组织时新增店铺/门店』功能上新,一键新增更高效!Tigshop 开源商城系统 JAVA v5.8.27 正式发布
java·商城系统·开源商城系统·tigshop
Full Stack Developme4 小时前
JDK 发展历史
java·开发语言
dreamsever4 小时前
OpenTelemetry可观测系统之Metrics学习
java·前端·学习
Xiacqi14 小时前
Spring全局异常处理
java·后端
Ting-yu4 小时前
Spring AI Alibaba零基础速成(3) ---- ChatClient使用
java·spring·spring cloud·spring ai
升鲜宝供应链及收银系统源代码服务5 小时前
升鲜宝供应链管理系统box_周转物功能设计模块详细开发文档(一)---升鲜宝生鲜配送供应链管理系统源代码服务
java·intellij-idea·生鲜配送源代码·升鲜宝生鲜配送源代码·后端app与手机端·b2b订货商城·客户订货系统源代码
红石程序员5 小时前
破解MyEclipse
java·ide·myeclipse