# flow-engine **Repository Path**: panda_student/flow-engine ## Basic Information - **Project Name**: flow-engine - **Description**: flow-engine - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-07 - **Last Updated**: 2025-11-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Solon Flow ## 项目介绍 Solon Flow 是一个基于 Solon 框架的轻量级工作流引擎,提供灵活的工作流定义、执行和管理能力。该项目采用模块化设计,支持无状态和有状态工作流,适用于各种业务流程编排场景。 ### 核心特性 - **声明式工作流定义**:支持 JSON/YAML 格式的工作流配置 - **多种节点类型**:支持开始节点、活动节点、并行节点、结束节点等 - **条件分支**:支持基于表达式的条件路由 - **任务执行**:支持组件化任务执行和脚本任务 - **状态管理**:支持有状态工作流的持久化和状态跟踪 - **扩展机制**:支持自定义驱动器和容器 - **高性能**:基于内存的高效执行引擎 ### 架构设计 Solon Flow 采用面向对象设计,遵循 SOLID 原则,实现高内聚、低耦合的架构: - **FlowEngine**:工作流引擎核心接口 - **Chain**:工作流链定义 - **Node**:工作流节点 - **Task**:任务定义 - **FlowDriver**:工作流驱动器 - **Container**:组件容器 ## 快速开始 ### 环境要求 - Java 8+ - Maven 3.6+ - Solon 3.5.2+ ### 依赖配置 在 `pom.xml` 中添加依赖: ```xml org.noear solon-flow 3.5.2 ``` ### 基本使用示例 #### 1. 简单工作流执行 ```java import org.noear.solon.flow.Chain; import org.noear.solon.flow.FlowContext; import org.noear.solon.flow.FlowEngine; public class SimpleFlowExample { public static void main(String[] args) { // 创建工作流引擎 FlowEngine flowEngine = FlowEngine.newInstance(); // 解析工作流配置 Chain chain = Chain.parseByText(""" { "id": "simple-flow", "layout": [ { "id": "start", "type": "start", "link": "task1" }, { "id": "task1", "type": "activity", "task": "context.put('result', 'Hello Flow!')", "link": "end" }, { "id": "end", "type": "end" } ] } """); // 执行工作流 FlowContext context = FlowContext.of(); flowEngine.eval(chain, context); System.out.println("执行结果: " + context.get("result")); } } ``` #### 2. 使用 YAML 配置文件 创建 `flow/simple.chain.yml` 文件: ```yaml id: "simple-flow" layout: - id: "start" type: "start" link: "task1" - id: "task1" type: "activity" task: "@helloComponent" link: "end" - id: "end" type: "end" ``` Java 代码: ```java import org.noear.solon.annotation.Component; import org.noear.solon.flow.FlowContext; import org.noear.solon.flow.FlowEngine; import org.noear.solon.flow.Node; import org.noear.solon.flow.TaskComponent; @Component("helloComponent") public class HelloComponent implements TaskComponent { @Override public void run(FlowContext context, Node node) { context.put("result", "Hello from Component!"); System.out.println("执行组件任务: " + node.getId()); } } public class YamlFlowExample { public static void main(String[] args) { FlowEngine flowEngine = FlowEngine.newInstance(); // 加载配置文件 flowEngine.load("classpath:flow/simple.chain.yml"); FlowContext context = FlowContext.of(); flowEngine.eval("simple-flow", context); System.out.println("执行结果: " + context.get("result")); } } ``` #### 3. 条件分支工作流 ```java import org.noear.solon.flow.Chain; import org.noear.solon.flow.FlowContext; import org.noear.solon.flow.FlowEngine; public class ConditionalFlowExample { public static void main(String[] args) { FlowEngine flowEngine = FlowEngine.newInstance(); Chain chain = Chain.parseByText(""" { "id": "conditional-flow", "layout": [ { "id": "start", "type": "start", "link": "decision" }, { "id": "decision", "type": "activity", "task": "context.put('score', 85)", "link": [ { "nextId": "excellent", "when": "score >= 90" }, { "nextId": "good", "when": "score >= 80" }, { "nextId": "pass", "when": "score >= 60" }, { "nextId": "fail" } ] }, { "id": "excellent", "type": "activity", "task": "context.put('grade', '优秀')", "link": "end" }, { "id": "good", "type": "activity", "task": "context.put('grade', '良好')", "link": "end" }, { "id": "pass", "type": "activity", "task": "context.put('grade', '及格')", "link": "end" }, { "id": "fail", "type": "activity", "task": "context.put('grade', '不及格')", "link": "end" }, { "id": "end", "type": "end" } ] } """); FlowContext context = FlowContext.of(); flowEngine.eval(chain, context); System.out.println("成绩等级: " + context.get("grade")); } } ``` #### 4. 并行执行工作流 ```java import org.noear.solon.flow.Chain; import org.noear.solon.flow.FlowContext; import org.noear.solon.flow.FlowEngine; public class ParallelFlowExample { public static void main(String[] args) { FlowEngine flowEngine = FlowEngine.newInstance(); Chain chain = Chain.parseByText(""" { "id": "parallel-flow", "layout": [ { "id": "start", "type": "start", "link": "parallel" }, { "id": "parallel", "type": "parallel", "link": ["task1", "task2", "task3"] }, { "id": "task1", "type": "activity", "task": "context.incr('count'); System.out.println('任务1完成')", "link": "join" }, { "id": "task2", "type": "activity", "task": "context.incr('count'); System.out.println('任务2完成')", "link": "join" }, { "id": "task3", "type": "activity", "task": "context.incr('count'); System.out.println('任务3完成')", "link": "join" }, { "id": "join", "type": "parallel", "link": "end" }, { "id": "end", "type": "end" } ] } """); FlowContext context = FlowContext.of(); flowEngine.eval(chain, context); System.out.println("并行任务完成数量: " + context.get("count")); } } ``` ## 高级特性 ### 有状态工作流 Solon Flow 支持有状态工作流,可以持久化工作流状态,支持中断和恢复: ```java import org.noear.solon.flow.FlowContext; import org.noear.solon.flow.FlowEngine; import org.noear.solon.flow.stateful.FlowStatefulService; import org.noear.solon.flow.stateful.controller.BlockStateController; import org.noear.solon.flow.stateful.repository.InMemoryStateRepository; public class StatefulFlowExample { public static void main(String[] args) { FlowEngine flowEngine = FlowEngine.newInstance(); // 配置有状态服务 FlowStatefulService statefulService = flowEngine.statefulService(); statefulService.setController(new BlockStateController()); statefulService.setRepository(new InMemoryStateRepository()); // 加载有状态工作流配置 flowEngine.load("classpath:flow/stateful-flow.yml"); // 执行有状态工作流 String instanceId = "workflow-instance-001"; FlowContext context = FlowContext.of(instanceId); // 第一次执行 flowEngine.eval("stateful-flow", context); // 后续可以基于实例ID恢复执行 // flowEngine.eval("stateful-flow", instanceId, context); } } ``` ### 自定义驱动器 支持自定义工作流驱动器,实现特定的执行逻辑: ```java import org.noear.solon.flow.*; import org.noear.solon.flow.driver.AbstractFlowDriver; public class CustomFlowDriver extends AbstractFlowDriver { @Override public void handleTask(FlowExchanger exchanger, Task task) throws Throwable { System.out.println("自定义驱动器处理任务: " + task.getNode().getId()); // 自定义任务处理逻辑 if ("specialTask".equals(task.getNode().getId())) { // 特殊处理逻辑 exchanger.context().put("customResult", "特殊任务已处理"); } // 调用父类处理逻辑 super.handleTask(exchanger, task); } } // 使用自定义驱动器 FlowEngine flowEngine = FlowEngine.newInstance(new CustomFlowDriver()); ``` ### 拦截器机制 支持工作流执行拦截器,用于日志记录、权限验证等: ```java import org.noear.solon.flow.intercept.ChainInterceptor; import org.noear.solon.flow.intercept.ChainInvocation; public class LoggingInterceptor implements ChainInterceptor { @Override public void intercept(ChainInvocation invocation) throws Throwable { System.out.println("工作流开始执行: " + invocation.getChain().getId()); long startTime = System.currentTimeMillis(); try { invocation.invoke(); } finally { long endTime = System.currentTimeMillis(); System.out.println("工作流执行完成,耗时: " + (endTime - startTime) + "ms"); } } } // 注册拦截器 flowEngine.addInterceptor(new LoggingInterceptor()); ``` ## 配置参考 ### 工作流配置格式 #### JSON 格式 ```json { "id": "workflow-id", "title": "工作流标题", "driver": "driver-name", "layout": [ { "id": "node1", "type": "start", "title": "开始节点", "link": "node2", "task": "@componentName", "when": "condition-expression", "meta": { "key1": "value1", "key2": ["array", "values"] } } ] } ``` #### YAML 格式 ```yaml id: "workflow-id" title: "工作流标题" driver: "driver-name" layout: - id: "node1" type: "start" title: "开始节点" link: "node2" task: "@componentName" when: "condition-expression" meta: key1: "value1" key2: ["array", "values"] ``` ### 节点类型 - **start**: 开始节点 - **activity**: 活动节点 - **parallel**: 并行节点 - **end**: 结束节点 - **decision**: 决策节点(已弃用,使用 activity + when 条件) ### 任务表达式 - **组件调用**: `@componentName` - **脚本执行**: `context.put('key', 'value')` - **复合任务**: `F:tag/fun1;R:tag/rule1` ## 最佳实践 ### 1. 工作流设计原则 - 保持工作流简洁,避免过度复杂的嵌套 - 合理使用并行节点提高执行效率 - 为关键节点添加有意义的标题和元数据 - 使用条件分支处理业务逻辑 ### 2. 性能优化 - 合理使用有状态工作流,避免不必要的状态持久化 - 对于高频执行的工作流,考虑使用内存存储 - 使用合适的评估器(如 Aviator、Beetl)提高表达式执行效率 ### 3. 错误处理 - 使用 try-catch 处理任务执行异常 - 配置合适的重试机制 - 记录详细的执行日志 ## 扩展开发 ### 自定义组件 ```java import org.noear.solon.annotation.Component; import org.noear.solon.flow.FlowContext; import org.noear.solon.flow.Node; import org.noear.solon.flow.TaskComponent; @Component("businessComponent") public class BusinessComponent implements TaskComponent { @Override public void run(FlowContext context, Node node) { // 业务逻辑实现 String businessData = context.get("businessData"); // 处理业务数据 String result = processBusiness(businessData); // 将结果放回上下文 context.put("result", result); } private String processBusiness(String data) { // 业务处理逻辑 return "Processed: " + data; } } ``` ### 自定义评估器 ```java import org.noear.solon.flow.Evaluation; public class CustomEvaluation implements Evaluation { @Override public Object eval(String expression, Object context) { // 自定义表达式评估逻辑 if (expression.startsWith("custom:")) { return evaluateCustomExpression(expression.substring(7), context); } // 默认评估逻辑 return null; } private Object evaluateCustomExpression(String expression, Object context) { // 自定义表达式解析逻辑 return "Custom Evaluation Result"; } } ``` ## 故障排除 ### 常见问题 1. **工作流无法启动** - 检查工作流配置格式是否正确 - 确认开始节点已正确定义 - 检查依赖组件是否已注册 2. **任务执行失败** - 检查任务表达式语法 - 确认组件是否存在且可访问 - 查看详细错误日志 3. **有状态工作流状态丢失** - 检查状态存储配置 - 确认实例ID的唯一性 - 验证状态持久化逻辑 ### 日志调试 启用详细日志记录工作流执行过程: ```yaml solon.logging.logger: org.noear.solon.flow: DEBUG ``` ## 贡献指南 欢迎为 Solon Flow 项目贡献代码!请遵循以下步骤: 1. Fork 项目仓库 2. 创建功能分支 3. 提交代码变更 4. 创建 Pull Request ## 许可证 Solon Flow 基于 Apache License 2.0 开源协议发布。 ## 相关资源 - [Solon 官方网站](https://solon.noear.org/) - [项目文档](https://solon.noear.org/flow/) - [示例代码](https://github.com/noear/solon-flow/tree/master/solon-flow-core/src/test/java) --- *本文档基于 Solon Flow 3.5.2 版本编写*