轻量级流程编排框架,Solon Flow v3.5.0 发布

Solon Flow 是一个轻量级流程编排框架(采用 yaml 或 json 偏平式编排格式)

  • 支持无状态流程
    • 可用于计算(或任务)的编排场景
    • 可用于业务规则和决策处理型的编排场景
  • 支持有状态流程
    • 可用于办公审批型(有状态、可中断,人员参与)的编排场景
    • 可用于长时间流程(结合自动前进,等待介入)的编排场景

有可视化的设计器:

同时兼容 java8 ~ java24。也可嵌入到 SpringBoot、jFinal、Vert.x 等框架中使用。嵌入第三方框架的示例:

一、最近更新了什么?

本次更新,统一了"无状态"、"有状态"流程的基础:引擎、驱动。通过上下文来识别是否为有状态及相关支持。

FlowContext 改为接口,增加了两个重要的方法:

java 复制代码
boolean isStateful();
StatefulSupporter statefulSupporter();

且,FlowContext 做了分离。解决了,之前在实例范围内不可复用的问题。

兼容说明

  • stateful 相关概念与接口有调整
  • FlowContext 改为接口,并移除 result 字段(所有数据基于 model 交换)
  • FlowContext 内置实现分为:StatelessFlowContext 和 StatefulFlowContext。通过 FlowContext.of(...) 实例化。(也可按需定制)
  • StateRepository 接口的方法命名调整,与 StatefulSupporter 保持一致性

升级请做好调整与测试。

具体更新

  • 新增 solon-flow iterator 循环网关($for, $in
  • 新增 solon-flow activity 节点流入流出模式($imode, $omode),用于二次定制开发
  • 添加 solon-flow ChainInterceptor:onNodeStart, onNodeEnd 方法(扩展拦截的能力)
  • 添加 solon-flow 操作:Operation.BACK_JUMP, FORWARD_JUMP
  • 添加 solon-flow FlowContext:incrGet, incrAdd
  • 添加 solon-flow aot 配置
  • 添加 solon-flow StatefulSupporter 接口,方便 FlowContext 对有状态流程提供支持
  • 添加 solon-flow FlowDriver:postHandleTask 方法(允许两段式提交任务执行,利于有状态与无状态的驱动定制)
  • 添加 solon-flow FlowContext:exchanger 方法(可获取 FlowExchanger 实例)
  • 调整 solon-flow FlowContext 拆分为:FlowContext(对外,可复用) 和 FlowExchanger(对内)
  • 调整 solon-flow FlowContext 移除 result 字段(所有数据基于 model 交换)
  • 调整 solon-flow FlowContext get 改为返回 Object(之前为 T),新增 getAs 返回 T(解决 get 不能直接打印的问题)
  • 调整 solon-flow 移除 StatefulSimpleFlowDriver 功能合并到 SimpleFlowDriver(简化为一个驱动,同时支持有状态与无状态流程)
  • 调整 solon-flow 新增 stateless 包,明确 "有状态" 与 "无状态" 两个概念(StatelessFlowContext 和 StatefulFlowContext)
  • 调整 solon-flow FlowStatefulService 接口,每个方法的 context 参数移到最后位(保持一致性)
  • 调整 solon-flow StateRepository 接口的方法命名,与 StatefulSupporter 保持一致性
  • 调整 solon-flow Chain 拆分为:Chain 和 ChainDecl

两对拆分类的定位:

  • FlowContext 侧重对外,可复用(用于传参、策略,状态)。有 StatelessFlowContext 和 StatefulFlowContext 两种内置实现。
  • FlowExchanger 侧重对内,不可复用(用于控制、中间临时状态或变量)
  • Chain 为运行态(不可修改)
  • ChainDecl 为声明或配置态(可以随时修改)

应用示例:

java 复制代码
//FlowContext 构建
FlowContext context = FlowContext.of(); //无状态的
FlowContext context = FlowContext.of("1"); //无状态的
FlowContext context = FlowContext.of("1", stateController); //有状态控制的
FlowContext context = FlowContext.of("1", stateController, stateRepository); //有状态控制的和状态持久化的


//Chain 手动声明
Chain chain = new ChainDecl("d3", "风控计算").create(decl -> {
            decl.addNode(NodeDecl.startOf("s").linkAdd("n2"));
            decl.addNode(NodeDecl.activityOf("n1").title("基本信息评分").linkAdd("g1").task("@base_score"));
            decl.addNode(NodeDecl.exclusiveOf("g1").title("分流")
                    .linkAdd("e", l -> l.title("优质用户(评分90以上)").condition("score > 90"))
                    .linkAdd("n2", l -> l.title("普通用户")) //没条件时,做为默认
            );
            decl.addNode(NodeDecl.activityOf("n2").title("电商消费评分").linkAdd("n3").task("@ec_score"));
            decl.addNode(NodeDecl.activityOf("n3").title("黑名单检测").linkAdd("e").task("@bl_score"));
            decl.addNode(NodeDecl.endOf("e").task("."));
        });

二、特色展示

1、采用 yaml 或 json 偏平式编排格式

偏平式编排,没有深度结构(所有节点平铺,使用 link 描述连接关系)。配置简洁,关系清晰

yaml 复制代码
# c1.yml
id: "c1"
layout: 
  - { id: "n1", type: "start", link: "n2"}
  - { id: "n2", type: "activity", link: "n3"}
  - { id: "n3", type: "end"}

还支持简化模式(能自动推断的,都会自动处理),具体参考相关说明

yaml 复制代码
# c1.yml
id: "c1"
layout: 
  - { type: "start"}
  - { task: ""}
  - { type: "end"}

2、表达式与脚本自由

yaml 复制代码
# c2.yml
id: "c2"
layout: 
  - { type: "start"}
  - { when: "order.getAmount() >= 100", task: "order.setScore(0);"}
  - { when: "order.getAmount() > 100 && order.getAmount() <= 500", task: "order.setScore(100);"}
  - { when: "order.getAmount() > 500 && order.getAmount() <= 1000", task: "order.setScore(500);"}
  - { type: "end"}

3、元数据配置,为扩展提供了无限空间

元数据主要有两个作用:(1)为任务运行提供配置支持(2)为视图编辑提供配置支持

yaml 复制代码
# c3.yml
id: "c3"
layout: 
  - { id: "n1", type: "start", link: "n2"}
  - { id: "n2", type: "activity", link: "n3", meta: {cc: "demo@noear.org"}, task: "@MetaProcessCom"}
  - { id: "n3", type: "end"}

通过组件方式,实现元数据的抄送配置效果

java 复制代码
@Component("MetaProcessCom")
public class MetaProcessCom implements TaskComponent {
    @Override
    public void run(FlowContext context, Node node) throws Throwable {
       String cc = node.getMeta("cc");
       if(Utils.isNotEmpty(cc)){
           //发送邮件...
       }
    }
}

4、事件广播与回调支持

广播(即只需要发送),回调(即发送后要求给答复)

yaml 复制代码
id: f4
layout:
  - task: |
      //只发送
      context.<String,String>eventBus().send("demo.topic", "hello");  //支持泛型(类型按需指定,不指定时为 object)
  - task: |
      //发送并要求响应(就是要给答复)
      String rst = context.<String,String>eventBus().sendAndRequest("demo.topic.get", "hello");
      System.out.println(rst);

5、支持无状态、有状态两种应用

支持丰富的应用场景:

  • 无状态流程
    • 可用于计算(或任务)的编排场景
    • 可用于业务规则和决策处理型的编排场景
  • 有状态流程
    • 可用于办公审批型(有状态、可中断,人员参与)的编排场景
    • 可用于长时间流程(结合自动前进,等待介入)的编排场景

自身也相当于一个低代码的运行引擎(单个配置文件,也可满足所有的执行需求)。

6、驱动定制(是像 JDBC 有 MySql, PostgreSQL,还可能有 Elasticsearch)

这是一个定制后的,支持基于状态驱动的流引擎效果。

java 复制代码
public class DemoFlowDriver implements FlowDriver {
    ...
}

FlowEngine flowEngine =FlowEngine.newInstance(new DemoFlowDriver());

StateController stateController = new ActorStateController("actor");
StateRepository stateRepository = new InMemoryStateRepository();
                
var context = FlowContext.of("i1", stateController, stateRepository).put("actor", "陈鑫");

//获取上下文用户的活动节点
var task = flowEngine.statefulService().getTask("f1", context);

assert "step2".equals(task.getNode().getId());
assert StateType.UNKNOWN == task.getState(); //没有权限启动任务(因为没有配置操作员)

//提交操作
flowEngine.statefulService().postOperation(context, "f1", task.getNode().getId(), Operation.FORWARD);

流程配置样例:

yaml 复制代码
id: f1
layout:
  - {id: step1, title: "发起审批", type: "start"}
  - {id: step2, title: "抄送", meta: {cc: "吕方"}, task: "@OaMetaProcessCom"}
  - {id: step3, title: "审批", meta: {actor: "陈鑫", cc: "吕方"}, task: "@OaMetaProcessCom"}
  - {id: step4, title: "审批", type: "parallel", link: [step4_1, step4_2]}
  - {id: step4_1, meta: {actor: "陈宇"}, link: step4_end}
  - {id: step4_2, meta: {actor: "吕方"}, link: step4_end}
  - {id: step4_end, type: "parallel"}
  - {id: step5, title: "抄送", meta: {cc: "吕方"}, task: "@OaMetaProcessCom"}
  - {id: step6, title: "结束", type: "end"}

对于驱动器的定制,我们还可以:定制(或选择)不同的脚本执行器、组件容器实现等。

相关推荐
奋进的芋圆20 分钟前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin37 分钟前
设计模式之桥接模式
java·设计模式·桥接模式
model200537 分钟前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉1 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国1 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882481 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈2 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_992 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
沛沛老爹2 小时前
Java泛型擦除:原理、实践与应对策略
java·开发语言·人工智能·企业开发·发展趋势·技术原理
专注_每天进步一点点2 小时前
【java开发】写接口文档的札记
java·开发语言