Solon v3.8.0

graph - GraphSpec、DSL 与序列化互转

</> markdown
2026年1月5日 上午11:16:21

在之前的章节中,我们学习了如何用 Java 代码编排流程。但在实际生产中,我们往往需要一个可视化界面让业务人员拖拽流程,或者将流程定义存在数据库中动态加载。

这就是本篇的主角:模型序列化与 DSL(领域特定语言)转换。

1、核心模型:Graph 与 GraphSpec 的关系

在 Solon-Flow 中,存在两个至关重要的模型,理解它们的区别是掌握动态性的关键:

  • GraphSpec (规格/图纸):它是一个纯粹的数据模型(POJO),代表了流程的“设计稿”。它极易被序列化为 JSON 或从 YAML 加载。
  • Graph (图实例/成品):它是经过引擎编译、校验后的执行对象。它拥有完整的索引结构,查询效率极高,不可直接修改。

2、实战:将流程持久化到数据库

为了实现“低代码”配置,我们需要将前端生成的配置保存。Solon-Flow 提供了极简的 API 进行转换。

  • 序列化:代码转 JSON

当你用 Java 编排好一个复杂的流程后,可以轻松将其转为 JSON 字符串存储。

Graph graph = Graph.create("order_flow", "订单流", spec -> { ... });

// 1. 将执行图转为 JSON 文本(以便存入数据库的 longtext 字段)
String json = graph.toJson();
  • 反序列化:JSON 转执行图

当系统启动或接收到外部请求时,从数据库读取字符串并还原。

String jsonFromDb = "..."; // 从数据库获取

// 1. 将文本解析回可执行的图
Graph graph = Graph.fromText(jsonFromDb);

3、DSL 的力量:YAML 与自定义解析

除了 JSON,Solon-Flow 还天然支持 YAML。YAML 具有更好的可读性,非常适合作为配置文件。

id: "discount_flow"
title: "折扣计算流程"
nodes:
  - id: "start"
    type: "start"
    links: 
      - next: "calc"
  - id: "calc"
    type: "activity"
    task: "@discountProcessor"
    links:
      - next: "end"
        when: "total > 100"
  - id: "end"
    type: "end"

你可以通自己设计解析器来实现自定义的 DSL。例如,如果你公司内部有一套自己的 XML 流程标准,只需要实现解析器将 XML 转为 GraphSpec 即可接入 Solon-Flow。

4、低代码后台的典型架构

通过“图影互转”,你可以轻松构建出一个功能强大的流程管理后台:

  • 前端:使用官方或第三方提供的专用开源设计器。或使用 LogicFlow 或 AntV X6 拖拽界面,输出标准 JSON。
  • 后端存储:后端接收 JSON,利用 GraphSpec.fromText(json) 进行格式校验,无误后存入数据库。
  • 动态发布:管理员点击“发布”按钮,后台调用 flowEngine.load(graph) 实时更新内存中的执行逻辑。

5、安全与校验建议

在反序列化外部传入的流程定义时,安全是首要考虑的问题:

  • Task 白名单:在解析 task: "@beanName" 时,建议校验该 Bean 是否属于预定义的业务处理类,防止恶意调用。
  • 拓扑校验:在 spec.create() 时,引擎会检查是否有孤立节点或死循环。务必捕获 FlowException 并反馈给前端。
  • 版本控制:持久化时建议带上版本号。利用 Graph.copy() 可以在旧版本的基础上快速生成新版本。

6、结语

从第一篇的“初体验”到本篇的“图影互转”,我们完整走过了 Solon-Flow 的设计精髓:

  • 轻量:不依赖繁重的数据库表,内存运行。
  • 解耦:业务动作与流转逻辑彻底分离。
  • 动态:支持运行时变更,适配千人千面。

掌握了 Solon-Flow,你便拥有了一套能够随业务快速迭代的“逻辑引擎”。