QLExpress使用及源码分析

简介: QLExpress是阿里巴巴开源的轻量级规则引擎,支持通过注解与YAML配置实现业务逻辑与代码解耦。提供AST语法树解析、上下文构建及高效执行机制,适用于动态规则场景。GitHub地址:https://github.com/alibaba/QLExpress

Git仓库:https://github.com/alibaba/QLExpress

1.示例Demo

1.实体构建

@Data
public class User {
    
    @QLAlias("姓名")
    private String name;
    
    @QLAlias("年龄")
    private Integer age;
    
    @QLAlias("性别")
    private String gender;
    
    @QLAlias("身高")
    private Double height;
    
    @QLAlias("体重")
    private Double weight;
}

2.接口定义

@Service(value = "userManagerImpl")
public class UserManagerImpl implements UserManager {
  ... ...
  @Override
  @QLRule("isAdult")
  public Boolean isAdult(@QLAlias("用户") User user) {
    throw new RuntimeException("不应该走到这里");
  }
    
  @Override
  @QLRule
  public BMIResult calculate(@QLAlias("用户") User user) {
    throw new RuntimeException("不应该走到这里");
  }
}

3.脚本编写

表达式内容维护在一个yaml里,默认扫描路径为:classpath*:/rules/**/*.yaml

这里为:user.yaml

// 对应上述接口1
isAdult:
  用户.年龄 >= 18
// 对应上述接口2
com.test.UserManagerImpl.calculate: |
  import com.test.Result;
  bmiResult = new Result();
  bmiValue = 用户.体重 / (患者.身高 * 患者.身高);
  bmiResult.setBmiValue(bmiValue);
  if (bmiValue < 18.5) {
    bmiResult.setMsg("体重过低");
  } else if (bmiValue > 23.9) {
    bmiResult.setMsg("体重过高");
  } else {
    bmiResult.setMsg("体重正常");
  }
  return bmiResult;

2.运行环节

QLExpressRunner如下图所示,从语法树分析、上下文、执行过程三个方面提供二次定制的功能扩展。

1.获取原始脚本,参数

  • QLRule中的value可以使用缺省值,对应yaml的key则为缺省值对应的ruleCode
  • 存在默认读取文件路径:com.c2f.boot.starter.rule.engine.QLExpressProperties
  • String rule为获取的原始脚本,后续基于此构建AST语法树

2.构建后续赋值上下文

  • 没取别名,默认构建一组:形参:value
  • 取别名,另构建一组:别名:value(后续yaml能汉化使用也是基于此)
  • 所以默认构建的上下文数量 = 形参个数 * 1,有别名 = 形参个数 * 2

3.调用执行

延迟执行

默认第一次执行即缓存

构建AST语法树

基于:com.ql.util.express.parse.KeyWordDefine4Java 构建

选择匹配工厂

递归解析

分解为Word[]:"sum",”=“,”0“,”;“,"for","(","i",......

Word[]转化为List《ExpressNode》:每一个word变得有意义:常量、变量、符号、分割符号

解析第一行:请领状态 = 药品请领单.执行状态

解析第二行:执行计划状态 = 执行计划.当前执行状态,clearDataStack后续也会当做一个指令使用

解析第三行,不再是loadAttr而是LoadData

或需是引包则loadData,变量定义是LoadAttr,未研究

真正执行

基于不同指令进入不同的重写方法

清除栈内数据

执行完毕返回


相关文章
|
2天前
|
机器学习/深度学习 存储 搜索推荐
第二章 基础算法
本文系统介绍了加密算法、排序算法及字符串处理等核心技术。涵盖对称与非对称加密、哈希摘要、电子签名原理,详解冒泡、快排、归并等排序算法的实现与优化,并结合实际场景讲解正则匹配与二分查找的应用,内容全面,适合技术学习与面试准备。
 第二章 基础算法
|
2天前
|
NoSQL Java 数据库连接
第七章 SpringBoot框架
SpringBoot简化了Spring开发,核心功能包括starter起步依赖、自动配置和内嵌服务器支持。通过条件注解实现Bean的自动化加载,支持自定义starter,并提供多种外部配置方式,提升开发效率与项目可维护性。(238字)
|
1天前
|
数据可视化 Java 关系型数据库
01-认识Activiti
工作流指具有审批流程的业务(如请假、报销等),通过流程引擎实现可视化管理。它支持单/多节点审批,广泛应用于CRM、TMS、WMS等系统。主流技术包括BPMN、Activiti、Flowable等,推动了泛微、金蝶、用友等企业的发展。
|
1天前
|
SQL 数据库连接 数据库
03-Activity代码实现
本文介绍了基于Activiti工作流引擎的入门实践,涵盖BPMN流程创建、部署、启动实例、任务查询与完成等核心操作。通过代码示例演示了流程定义部署、运行时实例管理及任务处理全过程,并结合数据库表变化说明执行效果,帮助开发者快速掌握工作流基本开发流程。
 03-Activity代码实现
|
1天前
|
Java Maven 数据库
02-Activiti工程搭建
本教程介绍如何在Idea中创建Maven工程并安装ActiBPM插件,包含插件下载、版本兼容性修复、手动修改JAR配置及验证安装等步骤,同时引入Activiti相关依赖,完成Spring Boot项目集成流程引擎的初步搭建。
02-Activiti工程搭建
|
1天前
|
存储 缓存 监控
EFC&CTO:缓存引发数据不一致问题排查与深度解析
EFC客户端在适配CTO测试时发现数据不一致问题,经排查为分布式缓存版本号回退导致读取旧数据,进而污染pagecache并写坏文件系统。通过维护递增版本号修复,最终解决问题并优化对POSIX语义的理解。
|
1天前
|
Java
HUTOOL-Word生成-Word07Writer
Hutool封装POI实现Word(docx)生成,提供Word07Writer类,支持字体、段落添加,简化文档创建。需引入hutool-all与poi-ooxml依赖,适用于Java环境下的简单Word操作。
|
2天前
|
jenkins Java 持续交付
SpringBoot集成Jenkins
基于阿里云CentOS环境,配置JDK1.8后通过YUM安装Jenkins,手动设置JDK路径并修改启动用户为root及端口为8081,成功启动服务。后续安装Git、Maven并配置阿里云镜像与环境变量,完成插件初始化设置,实现持续集成环境搭建。
|
2天前
|
Java 开发工具 数据安全/隐私保护
项目《中州养老》
《中州养老》是一个为养老院打造的单体后台管理系统,涵盖预约、入住、健康监测等核心功能,包含员工管理端与家属小程序端。项目采用SpringBoot+Vue3技术栈,集成Redis缓存、阿里云IoT及OSS存储,实现护理等级、床位管理、智能设备监测等模块,并通过RBAC权限控制、定时任务与WebSocket报警推送,提升系统安全性与实时性。
 项目《中州养老》
|
1天前
|
存储 SQL 关系型数据库
第四章 数据库
本文详解MySQL核心知识点,涵盖char与varchar区别、事务ACID特性、索引结构(B+树)、聚簇与二级索引、回表查询、索引失效场景及SQL优化策略,结合explain执行计划分析,提升数据库性能调优能力。