当前位置: 首页 > news >正文

Spring Boot 3 整合 LiteFlow:轻量级流程编排框架学习

Spring Boot 3 整合 LiteFlow:轻量级流程编排框架学习

前言

在现代企业级应用开发中,复杂的业务逻辑往往涉及多个步骤和条件判断,传统的硬编码方式容易导致代码耦合度高、维护困难。LiteFlow作为一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑。

什么是LiteFlow

LiteFlow是一个轻量级、高性能的组件式流程编排框架,主要特点包括:

  • 组件化设计:将复杂业务逻辑拆分为独立的组件,提高代码复用性
  • 规则驱动:通过配置文件定义流程规则,支持热加载
  • 高性能:基于责任链模式,执行效率高
  • 易扩展:支持多种节点类型(普通节点、条件节点、选择节点等)
  • Spring友好:与Spring Boot深度集成,支持依赖注入

核心概念

1. 节点类型

  • 普通节点(COMMON):执行具体业务逻辑
  • 条件节点(IF):根据条件判断执行不同分支
  • 选择节点(SWITCH):根据返回值选择执行路径
  • 循环节点(FOR/WHILE):支持循环执行

2. 流程表达式

LiteFlow使用EL表达式定义流程:

  • THEN(a, b, c):顺序执行
  • WHEN(a, b, c):并行执行
  • IF(x, a, b):条件执行
  • SWITCH(x).TO(a, b, c):选择执行

项目搭建

1. 添加依赖

pom.xml中添加LiteFlow依赖:

<dependencies><!-- Spring Boot 3 Web Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- LiteFlow Spring Boot Starter --><dependency><groupId>com.yomahub</groupId><artifactId>liteflow-spring-boot-starter</artifactId><version>2.11.0</version></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
</dependencies>

2. 配置文件

application.yml中配置LiteFlow:

liteflow:# 规则文件路径,支持多种格式:xml、json、ymlrule-source: config/*.xml

实战案例:订单处理流程

以一个电商订单处理流程为例,展示LiteFlow的使用方法。流程图如下:
在这里插入图片描述

1. 定义上下文对象

LiteFlow中的上下文(Context)是一个非常重要的概念,它是整个流程执行过程中的数据共享和传递的桥梁。上下文可以理解为流程中的“全局变量”或“共享数据区”,它存储了流程执行过程中需要用到的各种数据。这些数据可以是流程参数、业务数据、中间结果等。

LiteFlow中的每个组件都可以访问上下文,并从中获取所需的数据或将数据存入上下文中。组件之间通过上下文进行数据交换,而不需要直接相互调用或传递参数。这种设计方式降低了组件之间的耦合度,提高了流程的灵活性和可维护性。

首先创建订单上下文,用于在各个组件间传递数据:

package com.example.entity;import lombok.Data;
import lombok.experimental.Accessors;
import java.util.ArrayList;
import java.util.List;@Data
@Accessors(chain = true)
public class OrderContext {private String orderId;private String orderType;private List<String> processData = new ArrayList<>();
}

2. 创建业务组件

在LiteFlow中,业务逻辑被拆分为独立的组件,每个组件负责处理特定的业务功能。通过@LiteflowMethod定义组件内直接的节点方法。@LiteflowMethod注解则用于在组件类中声明可以被LiteFlow框架调用的方法。这个注解会指定该方法在流程中的节点类型(如普通节点、条件节点等)以及节点的一些属性(如节点ID、节点名称等)。在流程执行时,LiteFlow框架会根据流程定义中节点的配置来调用相应的组件方法,从而完成业务流程的执行,其中node_id的值即规则编排文件中表达式中对应的nodeId。

SWITCH组件详解

SWITCH组件的主要功能是在执行流程时根据预定义的条件进行分支选择。它通常用于处理流程中的决策点,类似于编程语言中的switch语句。在我们的订单处理场景中,SWITCH组件根据订单类型决定执行哪个流程节点:

  • 如果是ToC订单(即orderType=1),就会走to_c流程
  • 如果是ToB订单(即orderType=2),就会走to_b流程

这种设计的优势在于:

  1. 解耦业务逻辑:不同类型的订单处理逻辑完全分离,互不影响
  2. 易于扩展:新增订单类型时,只需添加新的处理分支即可
  3. 提高可维护性:每个分支的逻辑独立,便于调试和维护
业务节点组件设计

接下来我们需要定义处理订单的各业务节点。我们按照业务逻辑或者流程节点进行拆分成三个组件类:

  1. ToCHandlerCmp:专门处理ToC订单的组件类
  2. ToBHandlerCmp:专门处理ToB订单的组件类
  3. CommonHandleCmp:公共逻辑组件,包含可复用的业务节点
公共组件(CommonHandleCmp)

公共组件定义一些相同业务的处理节点,以便不同流程可以复用这些节点。同时也可以定义一些逻辑条件的节点,比如IF组件节点、SWITCH组件节点。在我们的案例中,公共组件包含:

  • SWITCH节点(order_x):根据订单类型选择执行路径
  • IF节点(order_k):判断是否为VIP订单
  • 通用处理节点(order_c、order_h):所有订单都需要执行的公共逻辑
package com.example.liteflow;import com.example.entity.OrderContext;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;@Slf4j
@LiteflowComponent
public class CommonHandleCmp {@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_SWITCH, nodeType = NodeTypeEnum.SWITCH, nodeId = "order_x", nodeName = "获取订单链路")public String processOrderType(NodeComponent nodeComponent){Integer orderCode = nodeComponent.getRequestData();return OrderTypeEnum.getChainId(orderCode);}@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "order_c", nodeName = "CNodeComponent")public void processC(NodeComponent nodeComponent){OrderContext orderContext = nodeComponent.getContextBean(OrderContext.class);List<String> processData = orderContext.getProcessData();processData.add("CNodeComponent");log.info("执行公共处理逻辑C");}@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_IF, nodeType = NodeTypeEnum.IF, nodeId = "order_k", nodeName = "KNodeComponent")public boolean processK(NodeComponent nodeComponent){OrderContext orderContext = nodeComponent.getContextBean(OrderContext.class);List<String> processData = orderContext.getProcessData();processData.add("KNodeComponent");String orderType = orderContext.getOrderType();log.info("判断是否为VIP订单: {}", orderType);return "vip".equals(orderType);}@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "order_h", nodeName = "HNodeComponent")public void processH(NodeComponent nodeComponent) {OrderContext orderContext = nodeComponent.getContextBean(OrderContext.class);List<String> processData = orderContext.getProcessData();processData.add("HNodeComponent");log.info("执行最终处理逻辑H");}@AllArgsConstructorenum OrderTypeEnum{TO_C(1, "to_c"),TO_B(2, "to_b");public final Integer code;public final String chainId;public static String getChainId(Integer code){return Arrays.stream(OrderTypeEnum.values()).filter(orderTypeEnum -> orderTypeEnum.code.equals(code)).findFirst().map(e -> e.chainId).orElseThrow(() -> new RuntimeException("不支持的订单类型"));}}
}
ToC订单处理组件(ToCHandleCmp)

ToC订单处理组件专门负责处理面向消费者(To Consumer)的订单业务逻辑。在这个组件中,我们定义了ToC订单特有的处理节点:

这些节点只在ToC订单流程中被调用,体现了组件化设计的优势。

package com.example.liteflow;import com.example.entity.OrderContext;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import lombok.extern.slf4j.Slf4j;
import java.util.List;@Slf4j
@LiteflowComponent
public class ToCHandleCmp {@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "order_a", nodeName = "ANodeComponent")public void processA(NodeComponent nodeComponent){OrderContext orderContext = nodeComponent.getContextBean(OrderContext.class);List<String> processData = orderContext.getProcessData();processData.add("ANodeComponent");log.info("执行ToC订单初始化逻辑A");}@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "order_d", nodeName = "DNodeComponent")public void processD(NodeComponent nodeComponent){OrderContext orderContext = nodeComponent.getContextBean(OrderContext.class);List<String> processData = orderContext.getProcessData();processData.add("DNodeComponent");log.info("执行VIP订单特殊处理逻辑D");}@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "order_f", nodeName = "FNodeComponent")public void processF(NodeComponent nodeComponent) {OrderContext orderContext = nodeComponent.getContextBean(OrderContext.class);List<String> processData = orderContext.getProcessData();processData.add("FNodeComponent");log.info("执行VIP订单后续处理逻辑F");}
}
ToB订单处理组件(ToBHandleCmp)

ToB订单处理组件专门负责处理面向企业(To Business)的订单业务逻辑。企业订单通常具有不同的处理规则和业务流程:

package com.example.liteflow;import com.example.entity.OrderContext;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import lombok.extern.slf4j.Slf4j;
import java.util.List;@Slf4j
@LiteflowComponent
public class ToBHandleCmp {@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "order_b", nodeName = "BNodeComponent")public void processB(NodeComponent nodeComponent){OrderContext orderContext = nodeComponent.getContextBean(OrderContext.class);List<String> processData = orderContext.getProcessData();processData.add("BNodeComponent");log.info("执行ToB订单初始化逻辑B");}@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "order_e", nodeName = "ENodeComponent")public void processE(NodeComponent nodeComponent) {OrderContext orderContext = nodeComponent.getContextBean(OrderContext.class);List<String> processData = orderContext.getProcessData();processData.add("ENodeComponent");log.info("执行普通订单处理逻辑E");}
}

3. 配置流程规则

流程规则是LiteFlow的核心,它定义了各个组件的执行顺序和条件。在我们的订单处理场景中,流程规则体现了以下业务逻辑:

  1. 主流程:首先通过SWITCH组件根据订单类型选择对应的处理分支
  2. ToC流程:执行ToC订单初始化 → 公共处理 → VIP判断分支 → 最终处理
  3. ToB流程:执行ToB订单初始化 → 公共处理 → VIP判断分支 → 最终处理
  4. 条件分支:根据是否为VIP订单执行不同的处理逻辑

src/main/resources/config/liteflow.xml中定义流程规则:

<?xml version="1.0" encoding="UTF-8"?>
<flow><chain name="order_handle">// 定义一个IF节点处理VIP订单分支逻辑// 如果order_k返回true(VIP订单),执行order_d和order_f// 如果order_k返回false(普通订单),执行order_eorder_if = IF(order_k, THEN(order_d, order_f), order_e);// 定义ToC订单的处理流程,用id标识流程为"to_c"// 顺序执行:ToC初始化 → 公共处理 → VIP判断分支to_c = THEN(order_a, order_c, order_if).id("to_c");// 定义ToB订单的处理流程,用id标识流程为"to_b"  // 顺序执行:ToB初始化 → 公共处理 → VIP判断分支to_b = THEN(order_b, order_c, order_if).id("to_b");// 主流程:先通过SWITCH选择订单类型分支,最后执行公共结束逻辑// SWITCH(order_x)会根据返回值选择执行to_c或to_b流程THEN(SWITCH(order_x).TO(to_c, to_b), order_h);</chain>
</flow>

流程规则解析:

  • order_if:定义了VIP订单的条件分支,通过IF组件判断订单类型
  • to_cto_b:分别定义了ToC和ToB订单的完整处理流程
  • 主流程:使用SWITCH组件实现订单类型的路由分发,最后统一执行结束处理

4. 创建控制器

控制器作为流程的入口点,负责接收HTTP请求并触发LiteFlow流程执行。在我们的设计中:

  • 通过路径参数orderType指定订单类型(1=ToC,2=ToB)
  • 请求体包含订单上下文信息
  • 使用FlowExecutor执行指定的流程链
  • 返回处理后的订单上下文数据
package com.example.controller;import com.example.entity.OrderContext;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/order")
@RequiredArgsConstructor
public class OrderController {private final FlowExecutor flowExecutor;@PostMapping("/process/{orderType}")public OrderContext processOrder(@PathVariable Integer orderType, @RequestBody OrderContext orderContext) {// 执行流程LiteflowResponse response = flowExecutor.execute2Resp("order_handle", orderType, orderContext);if (response.isSuccess()) {return response.getContextBean(OrderContext.class);} else {throw new RuntimeException("订单处理失败: " + response.getMessage());}}
}

5. 测试用例

package com.example.service;import com.alibaba.fastjson.JSON;
import com.example.entity.OrderContext;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
public class LiteFlowTest {@Autowiredprivate FlowExecutor flowExecutor;@Testpublic void testToCOrder() {OrderContext orderContext = new OrderContext();orderContext.setOrderId("1234");orderContext.setOrderType("vip");LiteflowResponse response = flowExecutor.execute2Resp("order_handle", 1, orderContext);orderContext = response.getContextBean(OrderContext.class);System.out.println("ToC VIP订单处理结果: " + JSON.toJSONString(orderContext));// 预期执行顺序: ANodeComponent -> CNodeComponent -> KNodeComponent -> DNodeComponent -> FNodeComponent -> HNodeComponent}@Testpublic void testToBOrder() {OrderContext orderContext = new OrderContext();orderContext.setOrderId("5678");orderContext.setOrderType("normal");LiteflowResponse response = flowExecutor.execute2Resp("order_handle", 2, orderContext);orderContext = response.getContextBean(OrderContext.class);System.out.println("ToB普通订单处理结果: " + JSON.toJSONString(orderContext));// 预期执行顺序: BNodeComponent -> CNodeComponent -> KNodeComponent -> ENodeComponent -> HNodeComponent}
}

异常处理

可以为链路配置异常处理:

@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_EXCEPTION)
public void processException(NodeComponent nodeComponent) {Exception exception = nodeComponent.getException();log.error("流程执行异常", exception);// 处理异常逻辑
}

数据传递

组件间可以通过多种方式传递数据:

// 通过上下文传递
OrderContext context = nodeComponent.getContextBean(OrderContext.class);// 通过请求数据传递
String requestData = nodeComponent.getRequestData();// 通过slot传递
nodeComponent.setSlot("key", "value");
String value = nodeComponent.getSlot("key");

文章参考:参考学习1

http://www.dtcms.com/a/545428.html

相关文章:

  • Rust:WebSocket支持的实现
  • 代刷开通建设网站Wordpress怎么添加购买页面
  • 做网站几个步骤网址推荐你会感谢我的
  • 黑马商城day7-消息可靠性
  • wpsapi
  • Postman实现jwt发送请求
  • 网站正在备案什么是网络营销 职能是什么
  • 【AI】Prompt 提示词工程
  • R语言高效数据处理-3个自定义函数笔记
  • 石家庄做网站备案有哪些公司品牌广告公司网站建设
  • 纯静态网站怎么入侵报告王妃
  • 郑州微盟网站建设公司网站建设的目的和目标
  • 仓颉中的字符串常用方法:语义一致性与高性能的设计哲学
  • 新MCU开发板快速上手指南:从开箱到精通
  • NestJS 项目创建
  • Apache Spark算法开发指导-特征转换-StandardScaler
  • 两个2的n次幂相加
  • 实时Java规范(RTSJ):从理论到实践的实时系统编程范式
  • 【Linux网络】进程间关系与守护进程
  • 建设部网站监理工程师报名wordpress菜单修改
  • vue 做网站 seo大连网站设计培训班
  • 【含文档+PPT+源码】基于SpringBoot和Vue的服装在线搭配及销售管理系统
  • 数据结构入门:深入理解顺序表与链表
  • 网站怎么做百度推广课题组网站怎么做
  • 前端React实战项目 全球新闻发布系统
  • 【React】 严格模式的 “双重执行” 机制,useEffect 执行两次
  • 使用 ngrok 在本地测试 Paddle Webhook 教程
  • React 入门 01:快速写一个React的HelloWorld项目
  • 地方旅游网站建设必要性网站怎么做站内美化
  • 设计网站栏目wordpress 三一重工