找回密码
 立即注册
首页 业界区 业界 灵动如画 —— 初识 Solon Graph Fluent API 编排 ...

灵动如画 —— 初识 Solon Graph Fluent API 编排

讲怔 昨天 06:15
Solon Flow 在提供 json/ xml 编排之后。还提供了一套极为丝滑的流程图 Fluent API。它让流程定义回归到程序员最熟悉的工具——代码。
通过 Fluent API,你可以像写 Java Stream 一样,通过链式调用快速勾勒出业务流转图。
1、环境准备

首先,确保你的 Java 项目中已经引入了 solon-flow 依赖:
  1. <dependency>
  2.     <groupId>org.noear</groupId>
  3.     solon-flow</artifactId>
  4. </dependency>
复制代码
2、核心概念:Graph 与 GraphSpec

在动手写代码前,需要理解两个关键概念:

  • Graph (图):流程的最终实体,包含所有节点和连线的运行逻辑。
  • GraphSpec (图规格/定义):它是构建图的“蓝图”。在 v3.8 之后,它是 Fluent API 操作的核心对象。
3、 实战:手动编排一个“订单处理流”

假设我们有一个简单的订单流程:开始 -> 检查库存 -> 支付 -> 结束。

  • 第一步:准备业务处理组件()
Solon-flow 的设计理念是 “逻辑与实现分离”。 我们先定义具体的业务动作:
  1. import org.noear.solon.annotation.Component;
  2. import org.noear.solon.flow.FlowContext;
  3. import org.noear.solon.flow.Node;
  4. import org.noear.solon.flow.TaskComponent;
  5. // 容器 Bean 的形式(此处以 Solon 为例)
  6. @Component("checkStock")
  7. public class CheckStockProcessor implements TaskComponent {
  8.     @Override
  9.     public void run(FlowContext ctx, Node node) throws Throwable {
  10.         System.out.println("--- 正在检查库存... ---");
  11.         ctx.put("stock_ok", true); // 在上下文中存入结果
  12.     }
  13. }
  14. //-------------
  15. // 普通 Java 类形式
  16. import org.noear.solon.annotation.Component;
  17. import org.noear.solon.flow.FlowContext;
  18. import org.noear.solon.flow.Node;
  19. import org.noear.solon.flow.TaskComponent;
  20. public class PayProcessor implements TaskComponent {
  21.     @Override
  22.     public void run(FlowContext context, Node node) throws Throwable {
  23.         System.out.println("--- 支付成功! ---");
  24.     }
  25. }
复制代码

  • 第二步:使用 Fluent API 编排流程
下面是本文的核心代码。我们通过 Graph.create 启动编排:
  1. import org.noear.solon.flow.Graph;
  2. public class FlowConfig {
  3.     public Graph buildOrderFlow() {
  4.         // 使用 Fluent API 构建
  5.         return Graph.create("order_flow", "订单处理流程", spec -> {
  6.             // 1. 定义开始节点并连接到下一个
  7.             spec.addStart("n1").title("开始").linkAdd("n2");
  8.             // 2. 定义业务节点,绑定对应的 Bean 标识
  9.             spec.addActivity("n2")
  10.                     .title("库存检查")
  11.                     .task("@checkStock") // 关联上面定义的 Bean(从容器获取)
  12.                     .linkAdd("n3");
  13.             spec.addActivity("n3")
  14.                     .title("支付")
  15.                     .task(new PayProcessor()) //硬编码方式(不用经过容器)
  16.                     .linkAdd("n4");
  17.             // 3. 定义结束节点
  18.             spec.addEnd("n4").title("结束");
  19.         });
  20.     }
  21. }
复制代码
4、关键 API 深度解析


  • spec.addStart(id) / addEnd(id):定义流程的边界。每一个图必须有且只有一个 Start 节点,可以有多个 End 节点。
  • spec.addActivity(id):这是最常用的节点,代表一个具体任务。
  • .task("@beanName"):这是核心联动点。@ 符号告诉 Solon 去容器中寻找对应的处理器。
  • .linkAdd(targetId):最简单的单向连线。它建立了一个从当前节点到目标节点的直接流转。
5、如何运行这个图?

有了 Graph 对象后,我们需要通过 FlowEngine 来触发它:
  1. import org.noear.solon.annotation.Component;
  2. import org.noear.solon.annotation.Inject;
  3. import org.noear.solon.flow.FlowContext;
  4. import org.noear.solon.flow.FlowEngine;
  5. import org.noear.solon.flow.Graph;
  6. @Component
  7. public class OrderService {
  8.     @Inject
  9.     FlowEngine flowEngine;
  10.     public void processOrder() {
  11.         // 1. 构建图(实际生产中通常会缓存此对象)
  12.         Graph orderGraph = new FlowConfig().buildOrderFlow();
  13.         // 2. 准备执行上下文(可以携带业务参数)
  14.         FlowContext context = FlowContext.of("ORD-20231024");
  15.         // 3. 执行流程
  16.         flowEngine.eval(orderGraph, context);
  17.     }
  18. }
复制代码
总结与预告

通过本文,你已经学会了如何不依赖任何配置文件,纯手工在内存中“画”出一个流程图。这种方式极大地提高了代码的可读性,并且让“流程定义”本身也成为了类型安全的代码。
但是,现实中的流程往往不是一条直线。 如果库存不足怎么办?如果金额巨大需要人工审批怎么办?
在后面的 《逻辑之魂 —— 节点的“条件流转”与表达式》 中,我们将引入“分支判断”,让你的 Graph 真正具备处理复杂业务的能力。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册