QLExpress使用及源码分析

简介: QLExpress是阿里开源的轻量级规则引擎,支持通过注解与YAML配置实现业务逻辑与代码解耦。结合实体别名、接口规则定义及脚本化表达式,实现动态计算与判断,如用户年龄判断、BMI计算等。支持AST语法树解析与上下文绑定,提供灵活的二次扩展能力,适用于复杂业务场景的延迟执行与缓存优化。

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,未研究

真正执行

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

清除栈内数据

执行完毕返回

相关文章
|
算法 NoSQL API
SpringCloud&Gateway网关限流
SpringCloud&Gateway网关限流
1390 7
|
监控 druid
druid 连接池监控报错 Sorry, you are not permitted to view this page.
druid 连接池监控报错 Sorry, you are not permitted to view this page.
2595 0
|
存储 算法 安全
SpringBoot 接口加密解密实现
【10月更文挑战第18天】
|
消息中间件 监控 Java
开发者如何使用云消息队列 RocketMQ 版
【10月更文挑战第12天】开发者如何使用云消息队列 RocketMQ 版
1784 100
|
负载均衡 安全 Java
【微服务系列笔记】Gateway
Gateway是Spring Cloud生态系统中的网关服务,作为微服务架构的入口,提供路由、负载均衡、限流、鉴权等功能。借助于过滤器和路由器,Gateway能够动态地管理请求流量,保障系统的安全和性能。
2171 7
|
存储 分布式数据库 数据库
Hbase学习二:Hbase数据特点和架构特点
Hbase学习二:Hbase数据特点和架构特点
581 0
|
负载均衡 应用服务中间件 nginx
nginx配置kibana访问用户名和密码认证、及无认证访问配置
nginx配置kibana访问用户名和密码认证、及无认证访问配置
780 0
|
SQL JSON 分布式计算
|
Java API 时序数据库
springboot如何配置influxdb
【6月更文挑战第24天】springboot如何配置influxdb
1085 0
|
机器学习/深度学习 人工智能 Java
【Sping Boot与机器学习融合:构建赋能AI的微服务应用实战】
【Sping Boot与机器学习融合:构建赋能AI的微服务应用实战】
379 1