强烈推荐强大的规则引擎框架LiteFlow

开发 前端
利用LiteFlow,你可以将瀑布流式的代码,转变成以组件为核心概念的代码结构,这种结构的好处是可以任意编排,组件与组件之间是解耦的,组件可以用脚本来定义,组件之间的流转全靠规则来驱动。LiteFlow拥有开源规则引擎最为简单的DSL语法。

环境:SpringBoot2.7.16


1. 简介

LiteFlow是一个非常强大的现代化的规则引擎框架,融合了编排特性和规则引擎的所有特性。

在每个公司的系统中,总有一些拥有复杂业务逻辑的系统,这些系统承载着核心业务逻辑,几乎每个需求都和这些核心业务有关,这些核心业务业务逻辑冗长,涉及内部逻辑运算,缓存操作,持久化操作,外部资源调取,内部其他系统RPC调用等等。时间一长,项目几经易手,维护成本就会越来越高。各种硬代码判断,分支条件越来越多。代码的抽象,复用率也越来越低,各个模块之间的耦合度很高。一小段逻辑的变动,会影响到其他模块,需要进行完整回归测试来验证。如要灵活改变业务流程的顺序,则要进行代码大改动进行抽象,重新写方法。实时热变更业务流程,几乎很难实现。LiteFlow为解耦逻辑而生,为编排而生,在使用LiteFlow之后,你会发现打造一个低耦合,灵活的系统会变得易如反掌!

LiteFlow优势

利用LiteFlow,你可以将瀑布流式的代码,转变成以组件为核心概念的代码结构,这种结构的好处是可以任意编排,组件与组件之间是解耦的,组件可以用脚本来定义,组件之间的流转全靠规则来驱动。LiteFlow拥有开源规则引擎最为简单的DSL语法。十分钟就可上手。

图片图片

组件可实时热更替,也可以给编排好的逻辑流里实时增加一个组件,从而改变你的业务逻辑。

图片图片

LiteFlow的脚本组件,支持众多脚本语言,完全和Java打通,你可以用脚本来实现任何逻辑。

图片图片

LiteFlow支持把编排规则和脚本放在数据库,注册中心中,还有可以任意扩展的接口,方便你定制。

图片图片

LiteFlow支持你能够想象处理的任何逻辑流程,如下流程:

图片图片

图片图片

规则文件

LiteFlow支持3中格式的规则文件定义:XML,JSON,YML。以下是XML示例:

<?xml versinotallow="1.0" encoding="UTF-8"?>
<flow>
    <chain name="example_01">
        THEN(a, b, c)
    </chain>
</flow>

规则说明

THNE:串行执行,a执行===》执行b===》执行c

WHEN:并行执行

<chain name="chain1">
    WHEN(a, b, c);
</chain>

SWITCH:选择执行

<chain name="chain1">
    SWITCH(a).to(b, c, d);
</chain>

图片图片

IF:条件执行

IF二元

<chain name="chain1">
    THEN(
        IF(x, a),
        b
    );
</chain>

图片图片

其中x为条件节点,为真的情况下,执行链路就为x->a->b,为假链路就为x->b。

IF三元

<chain name="chain1">
    THEN(
        IF(x, a, b),
        c
    );
</chain>

图片图片

还有其它很多的规则,这里不一一举例,可以查看官网。

2. 实战案例

环境配置

<dependency>
  <groupId>com.yomahub</groupId>
  <artifactId>liteflow-spring-boot-starter</artifactId>
  <version>2.11.4.2</version>
</dependency>

配置文件

#liteflow 配置
liteflow:
  rule-source: flows/*.el.xml


整个规则流程执行如下

图片图片


规则定义

<?xml versinotallow="1.0" encoding="UTF-8"?>
<flow>
    <chain name="processOrder">
        THEN(
          initOrder, 
          IF(amount, discountOrder),
          SWITCH(userType).to(vipDiscountOrder, normalDiscountOrder),
          completeOrder
        )
    </chain>
</flow>

这里的initOrder,amount,discountOrder等都是具体Node接口是bean的名称。

初始化订单组件

@Component("initOrder")
public class InitOrderComponent extends NodeComponent {
  @Override
  public void process() {
    System.out.println("初始化订单...") ;
    Order order = this.getContextBean(Order.class) ;
    double sum = order.getItems().stream().mapToDouble(item -> {
      return item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())).doubleValue() ;
    }).sum() ;
    order.setTotalAmount(BigDecimal.valueOf(sum));
  }
}

这里只做了计算订单总额。

判断订单总额节点

@Component("amount")
public class AmountComponent extends NodeIfComponent {


  @Override
  public boolean processIf() throws Exception {
    System.out.println("判断总金额,超过100元打折") ;
    Order order = this.getContextBean(Order.class) ;
    return order.getTotalAmount().doubleValue() >= 100D ;
  }


}

用户类型判断,执行哪个节点

@Component("userType")
public class UserTypeComponent extends NodeSwitchComponent {


  @Override
  public String processSwitch() throws Exception {
    User user = this.getContextBean(User.class) ;
    if (user.isVip()) {
      return "vipDiscountOrder" ;
    }
    return "normalDiscountOrder" ;
  }


}

上面返回的是具体节点的beanName。

VIP折扣节点

@Component("vipDiscountOrder")
public class VIPDiscountOrderComponent extends NodeComponent {


  @Override
  public void process() {
    System.out.println("VIP会员打9折") ;
    Order order = this.getContextBean(Order.class) ;
    order.setTotalAmount(order.getTotalAmount().multiply(BigDecimal.valueOf(9)).divide(BigDecimal.valueOf(10), RoundingMode.HALF_UP)) ;
  }
}

普通会员折扣节点

@Component("normalDiscountOrder")
public class NormalDiscountOrderComponent extends NodeComponent {


  @Override
  public void process() {
    System.out.println("普通会员不打折") ;
  }
}

完成节点

@Component("completeOrder")
public class CompleteOrderComponent extends NodeComponent  {


  @Override
  public void process() throws Exception {
    System.out.println("订单折扣执行完成,最后收尾...") ;
  }


}

以上是该规则流程的所有配置及定义。接下来进行测试

// 直接注入该类进行规则流程的启动执行
@Resource
private FlowExecutor flowExecutor;


@Test
public void testExample02() {
  Order order = new Order() ;
  order.setId(1L) ;
  order.setSno("S001") ;
  List<OrderItem> items = new ArrayList<>() ;
  items.add(new OrderItem(1L, 2, BigDecimal.valueOf(22))) ;
  items.add(new OrderItem(2L, 1, BigDecimal.valueOf(24.5))) ;
  items.add(new OrderItem(3L, 5, BigDecimal.valueOf(66.3))) ;
  order.setItems(items) ;
  User user = new User() ;
  user.setId(1L) ;
  user.setVip(false) ;
  LiteflowResponse response = flowExecutor.execute2Resp("processOrder", null, order, user);
  if (!response.isSuccess()) {
    Exception e = response.getCause() ;
    e.printStackTrace() ;
  } else {
    System.out.println("流程成功执行...") ;
    System.out.println("最终应付款:" + response.getContextBean(Order.class).getTotalAmount().doubleValue()) ;
  }
}

控制台将会输出详细的信息。

图片图片

修改用户类型后执行

图片图片

以上是本篇文章的全部内容,希望对你有所帮助。

责任编辑:武晓燕 来源: Spring全家桶实战案例源码
相关推荐

2020-02-24 10:06:43

Mac软件工具

2023-12-22 14:09:08

AI文本编辑器AiEditor

2011-06-30 17:41:46

SEO

2009-11-04 13:12:33

VB.NET继承类

2023-07-10 08:44:00

2012-02-03 15:13:27

JavaScript

2011-04-21 14:42:46

CSSHTML工具

2011-05-16 08:37:56

JavaScript库

2011-07-06 13:38:42

Web

2012-06-14 11:14:14

运维Firefox插件

2023-07-12 08:33:34

引擎LiteFlow编排

2014-04-11 13:12:10

前端技能前端必备

2020-02-16 10:45:30

Chrome数据火狐

2022-05-16 09:20:00

开发工具

2020-12-17 05:52:09

线程池ThreadPoolThreadPoolE

2022-09-07 11:38:04

async代码前端

2009-11-04 13:46:36

ADO.NET数据库

2023-12-07 19:13:48

Pythonprint

2020-02-24 19:40:22

WindowsSSH客户端

2022-09-16 15:54:56

开源C语言
点赞
收藏

51CTO技术栈公众号