流程编排
# 什么是 yt4j-flow?
yt4j-flow 是 yt4j 项目内置的一款轻量级流程编排引擎,旨在通过可视化的方式设计和执行业务流程。
类似于 LiteFlow (opens new window) 和 Gobrs-Async (opens new window) 这样的优秀流程编排框架,yt4j-flow 提供了流程的可视化设计和执行能力,但设计理念更加简单直观。
# 核心特性
# 1. 可视化流程设计
- 基于 Web 的拖拽式流程设计器
- 节点连线设计流程
- 实时预览流程结构
# 2. JSON 流程定义
- 流程以 JSON 格式存储
- 支持导入导出
- 便于版本管理和协作
# 3. Spring Bean 集成
- 通过
beanId直接调用 Spring Bean - 无需额外配置,开箱即用
- 支持依赖注入
# 4. 条件判断
- 支持 SpEL 表达式
- 灵活的条件分支控制
- 动态路由决策
# 5. 执行模式
- 当前: 仅支持同步调用
- 计划: 未来将支持异步调用
# 流程设计器
yt4j-flow 的流程设计器基于 [easy-flow](https://github.com/Q Monk/easy-flow) 项目进行二次开发。
# 设计器界面

# 增强功能
我们在原 easy-flow 基础上增加了两个字段:
- beanId: 填写 Spring Bean 的名称,用于流程节点执行时调用对应的 Bean
- condition: 编写 SpEL 表达式,用于条件判断和流程分支
# 流程定义格式
# JSON 结构说明
{
"name": "测试流程", // 流程名称
"nodeList": [ // 节点列表
{
"id": "59uh21rtyo", // 节点唯一ID
"name": "开始", // 节点名称
"type": "timer", // 节点类型: timer/task/end
"left": "266px", // 画布左侧位置
"top": "220px", // 画布顶部位置
"ico": "el-icon-time", // 图标
"state": "success" // 状态
},
{
"id": "4vcvxgcpo",
"name": "大于十岁处理",
"type": "task", // 任务节点
"left": "610px",
"top": "132px",
"ico": "el-icon-odometer",
"state": "success",
"beanId": "flowDemo1" // 对应的 Spring Bean 名称
},
{
"id": "tk07ay06hm",
"name": "小于十岁处理",
"type": "task",
"left": "597px",
"top": "376px",
"ico": "el-icon-odometer",
"state": "success",
"beanId": "flowDemo2" // 对应的 Spring Bean 名称
},
{
"id": "ewo9o56u8x",
"name": "流程结束",
"type": "end", // 结束节点
"left": "998px",
"top": "211px",
"ico": "el-icon-caret-right",
"state": "success"
}
],
"lineList": [ // 连线列表
{
"from": "59uh21rtyo", // 起始节点ID
"to": "4vcvxgcpo", // 目标节点ID
"label": "大于10岁", // 连线标签
"condition": "#age>10" // SpEL 条件表达式
},
{
"from": "59uh21rtyo",
"to": "tk07ay06hm",
"label": "小于10岁",
"condition": "#age<10"
},
{
"from": "tk07ay06hm",
"to": "ewo9o56u8x"
},
{
"from": "4vcvxgcpo",
"to": "ewo9o56u8x"
}
],
"id": "0"
}
# 使用指南
# 1. 创建流程 Bean
首先创建业务处理的 Spring Bean:
@Component("flowDemo1")
public class FlowDemo1 {
public void execute(FlowContext context) {
// 处理大于10岁的逻辑
System.out.println("执行流程Demo1,年龄大于10岁");
// 可以从 context 中获取参数
Integer age = context.get("age", Integer.class);
// 处理业务逻辑...
}
}
@Component("flowDemo2")
public class FlowDemo2 {
public void execute(FlowContext context) {
// 处理小于10岁的逻辑
System.out.println("执行流程Demo2,年龄小于10岁");
}
}
# 2. 设计流程
使用流程设计器设计流程:
- 拖拽节点到画布
- 配置节点属性(name、beanId)
- 连接节点
- 设置连线条件(condition)
- 导出 JSON 文件
# 3. 执行流程
将流程 JSON 文件保存到数据库或文件系统,通过流程引擎执行:
@Autowired
private FlowExecutor flowExecutor;
public void executeFlow(String flowJson, Map<String, Object> params) {
// 创建流程上下文
FlowContext context = new FlowContext();
context.setVariables(params);
// 执行流程
flowExecutor.execute(flowJson, context);
}
# 4. 流程持久化
yt4j-flow-server 模块提供流程的持久化支持:
- 流程定义存储到数据库
- 流程实例管理
- 流程执行历史查询
# 节点类型
# 1. 开始节点(timer)
- 流程的起始点
- 可以配置定时触发(计划功能)
# 2. 任务节点(task)
- 执行具体业务逻辑
- 通过
beanId关联 Spring Bean - 支持传入参数和返回结果
# 3. 结束节点(end)
- 流程的结束点
- 可以配置流程结束后的回调
# SpEL 表达式
流程连线支持使用 SpEL(Spring Expression Language)表达式进行条件判断:
# 常用示例
# 数字比较
#age > 10
#score >= 60
# 字符串判断
#status == 'APPROVED'
# 复杂条件
#age > 18 && #age < 60
#user.role == 'ADMIN' || #user.role == 'SUPER_ADMIN'
# 集合判断
#list.size() > 0
#user.roles.?[#this == 'ADMIN']
# 空值判断
#name != null
#list != null && #list.isEmpty() == false
# 典型应用场景
# 1. 审批流程
开始 → 部门经理审批 → (通过) → 总经理审批 → (通过) → 结束
↓ (拒绝) ↓ (拒绝)
结束(拒绝) 结束(拒绝)
# 2. 订单处理
开始 → 库存检查 → (有库存) → 创建订单 → 扣减库存 → 发送通知 → 结束
↓ (无库存)
结束(缺货)
# 3. 数据同步
开始 → 数据校验 → (通过) → 数据转换 → 写入目标系统 → 结束
↓ (不通过)
记录错误日志 → 结束
# 当前限制
# 已知限制
仅支持同步调用
- 当前版本所有节点串行执行
- 不支持并行执行
- 不支持异步回调
无内置前端
- yt4j-flow-server 暂时没有配套前端
- 可以使用独立的设计器工具
- 流程定义需要手动导入
简单编排
- 不支持复杂的流程控制(如循环、子流程)
- 不支持事务管理
- 不支持补偿机制
# 未来计划
- ✅ 异步调用支持
- ✅ 前端页面集成
- ✅ 审批流功能增强
- ✅ 流程监控和统计
- ✅ 更丰富的节点类型
# 与其他框架对比
| 特性 | yt4j-flow | LiteFlow | Gobrs-Async |
|---|---|---|---|
| 可视化设计 | ✅ | ❌ | ❌ |
| JSON 定义 | ✅ | ✅ | ❌ |
| Spring 集成 | ✅ | ✅ | ✅ |
| 异步支持 | ❌ | ✅ | ✅ |
| 复杂编排 | 简单 | 强大 | 强大 |
| 学习曲线 | 低 | 中 | 中 |
选择建议:
- 如果需要可视化设计和简单流程,选择 yt4j-flow
- 如果需要复杂的流程编排和高性能,选择 LiteFlow 或 Gobrs-Async
# 最佳实践
# 1. Bean 命名规范
// 推荐:使用有意义的 bean 名称
@Component("flow.approval.manager")
@Component("flow.order.create")
// 避免:使用无意义的名称
@Component("bean1")
@Component("testBean")
# 2. 流程设计原则
- 单一职责:每个节点只做一件事
- 流程清晰:避免过于复杂的嵌套
- 可测试性:节点逻辑独立,方便单元测试
# 3. 错误处理
@Component("flowDemo")
public class FlowDemo {
public void execute(FlowContext context) {
try {
// 业务逻辑
} catch (Exception e) {
// 记录错误日志
context.set("error", e.getMessage());
throw e; // 抛出异常,终止流程
}
}
}
# 参考资料
上次更新: 2026/01/04, 09:28:19