前端组件化(SpringBoot3实战:轻量编排复杂业务,打造可复用组件化流程)

前端组件化(SpringBoot3实战:轻量编排复杂业务,打造可复用组件化流程)
SpringBoot3实战:轻量编排复杂业务,打造可复用组件化流程

#我要上精选-全民写作大赛#

平时做业务开发,尤其是电商订单、审批流、数据处理这类场景,是不是经常被层层嵌套的if-else牵一发而动全身的硬编码流程搞崩溃?

改一个执行顺序,要翻遍整个方法;加一个分支逻辑,生怕漏判导致bug;多人协作开发,流程逻辑散落在各处,维护成本直线飙升。

后来在项目里接入了轻量国产开源框架 LiteFlow,彻底理顺了这类复杂业务逻辑。它主打零侵入、易上手、动态编排的特性,把整块业务拆成独立可复用的组件,流程规则单独配置管理,调整执行顺序、新增分支逻辑都不用改动原有代码,开发和维护效率直接拉满。

前端组件化(SpringBoot3实战:轻量编排复杂业务,打造可复用组件化流程)

一、前期准备:项目环境与核心依赖

先确认基础环境,保证兼容性:

  • JDK版本:17+
  • SpringBoot版本:3.2.5
  • liteflow:2.15.3 (最新稳定版)

新建SpringBoot3项目,只需要引入Web依赖和核心编排框架Starter。

1.1 引入Maven依赖

打开 pom.xml,添加以下依赖:

<!-- SpringBoot3 Web Starter -->    org.springframework.boot    spring-boot-starter-web<!-- 轻量流程编排框架 Starter -->    com.yomahub    liteflow-spring-boot-starter    2.15.3<!-- 工具包,可选 -->    cn.hutool    hutool-all    5.8.25

1.2 核心配置文件

在 application.yml 中添加极简配置,指定规则文件位置、开启日志,方便调试:

spring:  application:    name: springboot3-flow-demo# 流程编排核心配置liteflow:  # 规则文件路径,放在resources下  rule-source: flow/order-flow.el.xml  # 打印执行日志,排查问题更方便  print-execution-log: true  # 上下文槽大小,根据并发量调整  slot-size: 1024  # 支持热加载,修改规则无需重启服务  enable-monitor: true

配置完直接启动项目,无报错说明依赖集成成功,接下来进入核心实战环节。

二、核心实战:电商订单流程编排

以最常见的电商创建订单流程为例,拆解业务步骤:

  1. 参数校验:校验订单参数合法性
  2. 库存校验:校验商品库存是否充足
  3. 价格计算:计算商品总价、优惠抵扣
  4. 订单创建:生成订单数据
  5. 消息通知:推送订单创建成功消息

传统写法会把所有逻辑塞在一个方法里,我们用组件化+规则编排的方式重构,彻底解耦。

2.1 定义流程上下文(数据载体)

上下文用于在各个组件间传递数据,避免局部变量混乱,所有组件共享一份上下文数据:

import lombok.Data;import java.math.BigDecimal;/** * 订单流程上下文 * 存放整个流程的入参、中间结果、出参 */@Datapublic class OrderContext {    // 订单入参    private Long userId;    private Long goodsId;    private Integer goodsNum;    // 中间结果    private Boolean stockEnough;    private BigDecimal totalPrice;    private BigDecimal discountPrice;    // 最终结果    private Long orderId;    private String orderStatus;}

2.2 拆分业务组件(核心单元)

把每个业务步骤封装成独立组件,继承 NodeComponent,用注解标记组件ID,流程规则通过ID调用。

组件1:订单参数校验

import cn.hutool.core.util.ObjectUtil;import com.liteflow.demo.entity.OrderContext;import com.yomahub.liteflow.annotation.LiteflowComponent;import com.yomahub.liteflow.core.NodeComponent;import com.yomahub.liteflow.exception.FlowSystemException;@LiteflowComponent("orderCheckCmp")public class OrderCheckCmp extends NodeComponent {    @Override    public void process(){        // 获取上下文        OrderContext context = this.getContextBean(OrderContext.class);        // 执行业务校验        if (ObjectUtil.hasNull(context.getUserId(), context.getGoodsId(), context.getGoodsNum())) {            throw new FlowSystemException("订单参数不能为空");        }        if (context.getGoodsNum() <= 0) {            throw new FlowSystemException("商品数量必须大于0");        }        System.out.println("订单参数校验通过");    }}

组件2:商品库存校验

import com.liteflow.demo.entity.OrderContext;import com.yomahub.liteflow.annotation.LiteflowComponent;import com.yomahub.liteflow.core.NodeComponent;import com.yomahub.liteflow.exception.FlowSystemException;@LiteflowComponent("stockCheckCmp")public class StockCheckCmp extends NodeComponent {    @Override    public void process() {        OrderContext context = this.getContextBean(OrderContext.class);        // 模拟库存校验        boolean stockEnough = context.getGoodsNum() <= 100;        context.setStockEnough(stockEnough);        System.out.println("商品库存校验完成,是否充足:" + stockEnough);        if (!stockEnough) {            throw new FlowSystemException("库存不足,订单创建失败");        }    }}

组件3:价格计算(priceCalcCmp)

import com.liteflow.demo.entity.OrderContext;import com.yomahub.liteflow.annotation.LiteflowComponent;import com.yomahub.liteflow.core.NodeComponent;import java.math.BigDecimal;@LiteflowComponent("priceCalcCmp")public class PriceCalcCmp extends NodeComponent {    @Override    public void process() {        OrderContext context = this.getContextBean(OrderContext.class);        // 模拟商品单价(实际可从DB/缓存获取)        BigDecimal goodsPrice = new BigDecimal("99.9");        // 计算商品总价        BigDecimal totalPrice = goodsPrice.multiply(new BigDecimal(context.getGoodsNum()));        // 模拟优惠抵扣(满减/折扣逻辑)        BigDecimal discountPrice = totalPrice.multiply(new BigDecimal("0.9")).setScale(2, BigDecimal.ROUND_HALF_UP);        // 赋值到上下文        context.setTotalPrice(totalPrice);        context.setDiscountPrice(discountPrice);        System.out.println("价格计算完成,原价:" + totalPrice + ",优惠后:" + discountPrice);    }}

组件4:订单创建(orderCreateCmp)

import com.liteflow.demo.entity.OrderContext;import com.yomahub.liteflow.annotation.LiteflowComponent;import com.yomahub.liteflow.core.NodeComponent;import java.util.Random;@LiteflowComponent("orderCreateCmp")public class OrderCreateCmp extends NodeComponent {    @Override    public void process() {        OrderContext context = this.getContextBean(OrderContext.class);        // 模拟生成订单ID(实际用雪花算法/数据库自增)        long orderId = new Random().nextLong(1000000000L, 9999999999L);        // 赋值订单信息        context.setOrderId(orderId);        context.setOrderStatus("PENDING_PAY");        // 模拟入库操作        System.out.println("订单创建完成,订单ID:" + orderId + ",状态:待支付");    }}

组件5:消息通知(msgNotifyCmp)

import com.liteflow.demo.entity.OrderContext;import com.yomahub.liteflow.annotation.LiteflowComponent;import com.yomahub.liteflow.core.NodeComponent;@LiteflowComponent("msgNotifyCmp")public class MsgNotifyCmp extends NodeComponent {    @Override    public void process() {        OrderContext context = this.getContextBean(OrderContext.class);        // 模拟消息推送(MQ/短信/站内信)        System.out.println("消息通知成功:用户" + context.getUserId() + ",您的订单" + context.getOrderId() + "已创建,请及时支付");    }}

2.3 编写流程规则文件

在 resources/flow 目录下,创建 order-flow.el.xml 规则文件,用EL表达式编排组件执行顺序,想改流程直接改这个文件,无需动Java代码(实际项目中可以通过前端配置动态生成)。

<!--?xml version="1.0" encoding="UTF-8"?-->    <!-- 定义订单流程链,name为流程唯一标识 -->            <!-- THEN表示串行执行,WHEN表示并行执行 -->        THEN(        orderCheckCmp,        stockCheckCmp,        priceCalcCmp,        orderCreateCmp,        msgNotifyCmp        );    

规则语法极简,支持串行、并行、条件分支、循环、嵌套子流程,复杂业务轻松搞定。

三、接口调用:流程执行与结果处理

编写Controller接口,注入流程执行器,触发流程并返回结果,和普通接口开发无差异。

import com.yomahub.liteflow.core.FlowExecutor;import com.yomahub.liteflow.flow.LiteflowResponse;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController@RequestMapping("/order")public class OrderController {    // 注入流程执行器    @Resource    private FlowExecutor flowExecutor;    @PostMapping("/create")    public String createOrder(@RequestBody OrderContext context) {        // 执行流程,参数:流程ID,参数,上下文对象        LiteflowResponse response = flowExecutor.execute2Resp("createOrderChain","", context);        // 判断执行结果        if (response.isSuccess()) {            OrderContext result = response.getContextBean(OrderContext.class);            return "订单创建成功,订单ID:" + result.getOrderId() + ",状态:" + result.getOrderStatus();        } else {            return "订单创建失败,原因:" + response.getMessage();        }    }}

四、实战测试与常见问题

4.1 接口测试

用Postman调用接口,传入参数:

{    "userId": 1001,    "goodsId": 2001,    "goodsNum": 2}

控制台打印执行日志,接口返回订单创建成功;

若传入商品数量为200(大于库存100),则返回库存不足,流程终止,完全符合预期。

4.2 常见问题

  • 组件ID重复:每个组件的@LiteflowComponent(value)必须唯一,否则启动报错
  • 上下文获取失败:确保execute2Resp传入的上下文类和getContextBean一致
  • 规则文件不生效:检查rule-source路径是否正确,文件名后缀是否为.el.xml
  • 事务控制:建议在Service层控制事务,组件内只做业务逻辑处理

五、实战总结

这套轻量编排方案,对比传统硬编码优势太明显:

  • 解耦彻底:业务逻辑拆分成独立组件,可复用、易测试
  • 灵活可变:流程规则单独配置,动态修改无需重启服务
  • 上手极快:无复杂概念,会写Spring组件就能快速落地
  • 轻量高效:无额外中间件,性能损耗极低,适配高并发场景

不管是订单流程、审批流、数据清洗、任务调度,只要是多步骤、可编排的业务,都能套用这套方案,彻底告别代码臃肿、维护困难的痛点。

文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有