graph - GraphSpec、DSL 与序列化互转
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,你便拥有了一套能够随业务快速迭代的“逻辑引擎”。