Aviator 规则引擎介绍
先说结论: 规则简单:qlexpress或者avaitor;规则复杂:drools
最终选择是因为:足够轻量级,社区活跃度较好,最新jar包更新于22年4月
官网
git地址
String expression = "a=='河北省'&&((b=='男人'||c>=30)||d=='黄')";// 编译表达式Expression compiledExp = AviatorEvaluator.compile(expression);Map<String, Object> env = new HashMap<>();env.put("a", "河北省");env.put("b", "男人");env.put("c",1);env.put("d","黄");// 执行表达式System.out.println( compiledExp.execute(env));
1、引入背景
1.1 需求背景及面临问题
系统分案时,需要针对规则进行解析:
示例:
((省份 = 河北省)并且((城市 = 张家口市)或者(城市 = 石家庄市))并且(服务类型 = 信用卡)并且((委托金额 > 1000)并且(委托金额 < 50000)))或者((省份 = 河北省)并且(城市 = 石家庄市)并且(服务类型 = 互联网))
解析条件:
(省份 = 河北省)并且(城市 = 张家口市)并且(服务类型 = 信用卡)并且(委托金额 > 1000)并且(委托金额 < 50000)
(省份 = 河北省)并且(城市 = 石家庄市)并且(服务类型 = 信用卡)并且(委托金额 > 1000)并且(委托金额 < 50000)
(省份 = 河北省)并且(城市 = 石家庄市)并且(服务类型 = 互联网)
1.2 面临问题
系统架构复杂
系统的可维护性和维护成本提高
系统的整合复杂
增加“硬代码”业务规则的成本和风险
2 为什么选用Aviator
2.1 简介
高性能、轻量级的java语言实现的表达式求值引擎,主要用于各种表达式的动态求值
Aviator的设计目标是轻量级和高性能 ,相比于Groovy、JRuby的笨重,Aviator 非常小,加上依赖包也才450K,不算依赖包的话只有70K
其次,Aviator的实现思路与其他轻量级的求值器很不相同,其他求值器一般都 是通过解释的方式运行,而Aviator则是直接将表达式编译成Java字节码,交给 JVM去执行
简单来说,Aviator的定位是介于Groovy这样的重量级脚本语言和 IKExpression这样的轻量级表达式引擎之间。
2.2 特性介绍
支持大部分运算操作符,包括算术操作符、关系运算符、逻辑操作符、正则匹配操作符 、三元表达式 ,并且支持操作符的优先级和括号强制优先级,具体请看后面的操作符列表。
支持函数调用和自定义函数。
支持正则表达式匹配,类似Ruby、Perl的匹配语法,并且支持类Ruby的$digit指向匹配分组。自动类型转换,当执行操作的时候,会自动判断操作数类型并做相应转换,无法转换即抛异常。
支持传入变量,支持类似a.b.c的嵌套变量访问。
性能优秀。
2.3 整体结构
3 demo
3.1 引入pom
为啥选这个版本,因为这是按时间倒序的第二个稳定版本
<!-- https://mvnrepository.com/artifact/com.googlecode.aviator/aviator -->
<dependency><groupId>com.googlecode.aviator</groupId><artifactId>aviator</artifactId><version>5.3.0</version>
</dependency>
3.2 执行方式
execute():需要传递Map格式参数
exec():不需要传递Mappublic class Test {public static void main(String[] args) {// exec执行方式,无需传递Map格式String age = "18";System.out.println(AviatorEvaluator.exec("'His age is '+ age +'!'", age));// execute执行方式,需传递Map格式Map<String, Object> map = new HashMap<String, Object>();map.put("age", "18");System.out.println(AviatorEvaluator.execute("'His age is '+ age +'!'", map));}
}
3.3 支持函数
public class Test {public static void main(String[] args) {Map<String,Object> map = new HashMap<>();map.put("s1","123qwer");map.put("s2","123");System.out.println(AviatorEvaluator.execute("string.startsWith(s1,s2)",map));}
}
3.4 自定义函数
自定义函数要继承AbstractFunction类,重写目标方法。
public class Test {public static void main(String[] args) {// 注册自定义函数AviatorEvaluator.addFunction(new MultiplyFunction());// 方式1System.out.println(AviatorEvaluator.execute("multiply(12.23, -2.3)"));// 方式2Map<String, Object> params = new HashMap<>();params.put("a", 12.23);params.put("b", -2.3);System.out.println(AviatorEvaluator.execute("multiply(a, b)", params));}}class MultiplyFunction extends AbstractFunction{@Overridepublic AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {double num1 = FunctionUtils.getNumberValue(arg1, env).doubleValue();double num2 = FunctionUtils.getNumberValue(arg2, env).doubleValue();return new AviatorDouble(num1 * num2);}@Overridepublic String getName() {return "multiply";}}
3.5 运算符优先级
3.6 常量和变量
3.7 表达式Demo
public class Test {public static void main(String[] args) {String expression = "a+(b-c)>100";// 编译表达式Expression compiledExp = AviatorEvaluator.compile(expression);Map<String, Object> env = new HashMap<>();env.put("a", 100.3);env.put("b", 45);env.put("c", -199.100);// 执行表达式Boolean result = (Boolean) compiledExp.execute(env);System.out.println(result);}
}
3.8 数组和集合Demo
List和数组用list[0]和array[0],Map用map.date
public class Test {public static void main(String[] args) {final List<String> list = new ArrayList<>();list.add("hello");list.add(" world");final int[] array = new int[3];array[0] = 0;array[1] = 1;array[2] = 3;final Map<String, Date> map = new HashMap<>();map.put("date", new Date());Map<String, Object> env = new HashMap<>();env.put("list", list);env.put("array", array);env.put("map", map);System.out.println(AviatorEvaluator.execute("list[0]+':'+array[0]+':'+'today is '+map.date", env));}}
3.9 三元比较符
public class Test {public static void main(String[] args) {Map<String, Object> env = new HashMap<String, Object>();env.put("a", -5);String result = (String) AviatorEvaluator.execute("a>0? 'yes':'no'", env);System.out.println(result);}}
3.10 正则表达式匹配
public class Test {public static void main(String[] args) {String email = "hello2018@gmail.com";Map<String, Object> env = new HashMap<String, Object>();env.put("email", email);String username = (String) AviatorEvaluator.execute("email=~/([\\w0-8]+)@\\w+[\\.\\w+]+/ ? $1 : 'unknow' ", env);System.out.println(username);}
}
3.11 变量的语法糖衣
/*** CreateBy: haleyliu* CreateDate: 2018/12/25*/
public class Test {public static void main(String[] args) {User user = new User(1,"jack","18");Map<String, Object> env = new HashMap<>();env.put("user", user);String result = (String) AviatorEvaluator.execute(" '[user id='+ user.id + ',name='+user.name + ',age=' +user.age +']' ", env);System.out.println(result);}
}@Data
@AllArgsConstructor
@NoArgsConstructor
@NoArgsConstructor
@ToString
public class User {private int id;private String name;private String age;public User() {}}
3.12 nil对象[任何对象都比nil大除了nil本身]
AviatorEvaluator.execute("nil == nil"); //true AviatorEvaluator.execute(" 3> nil"); //true AviatorEvaluator.execute(" true!= nil"); //true AviatorEvaluator.execute(" ' '>nil "); //true AviatorEvaluator.execute(" a==nil "); //true,a is null
nil与String相加的时候,跟java一样显示为null
3.13 日期比较
public class Test {public static void main(String[] args) {Map<String, Object> env = new HashMap<String, Object>();final Date date = new Date();String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS").format(date);env.put("date", date);env.put("dateStr", dateStr);Boolean result = (Boolean) AviatorEvaluator.execute("date==dateStr",env);System.out.println(result);result = (Boolean) AviatorEvaluator.execute("date > '2009-12-20 00:00:00:00' ", env);System.out.println(result);result = (Boolean) AviatorEvaluator.execute("date < '2200-12-20 00:00:00:00' ", env);System.out.println(result);result = (Boolean) AviatorEvaluator.execute("date ==date ", env);System.out.println(result);}
}
4 语法手册
4.1 数据类型
Number类型:数字类型,支持两种类型,分别对应Java的Long和Double
任何整数都将被转换为Long
任何浮点数都将被转换为Double,包括用户传入的数值也是如此转换。
不支持科学计数法
支持十进制。如-1、100、2.3等。
整数也可以用十六进制表示,以 0x 或者 0X 开头的数字,比如 0xFF(255)、0xAB(171) 等等。
需要注意,整数相除的结果仍然是整数,比如例子中的 a/b 结果就是 0,遵循 java 的整数运算规则。
String类型: 字符串类型
单引号或者双引号括起来的文本串,如’hello world’
变量如果传入的是String或者Character也将转为String类型。
Bool类型:
常量true和false,表示真值和假值,与java的Boolean.TRUE和Boolean.False对应。
Pattern类型:
类似Ruby、perl的正则表达式,以//括起来的字符串,如//d+/
内部实现为java.util.Pattern。
变量类型:
与Java的变量命名规则相同,
变量的值由用户传入,如"a"、"b"等
nil类型: 常量nil,类似java中的null,
但是nil比较特殊,nil不仅可以参与==、!=的比较,也可以参与>、>=、<、<=的比较,
Aviator规定任何类型都n大于nil除了nil本身,nil==nil返回true。
用户传入的变量值如果为null,那么也将作为nil处理,nil打印为null。
4.2 算术运算符
支持常见的算术运算符,包括+ - / % 五个二元运算符和一元运算符"-“。
其中 - / %和一元的”-"仅能作用于Number类型。
"+"不仅能用于Number类型,还可以用于String的相加,或者字符串与其他对象的相加。
Aviator规定,任何类型与String相加,结果为String。
4.3 逻辑运算符
Avaitor的支持的逻辑运算符包括,一元否定运算符"!“,以及逻辑与的”&&“,逻辑或的”||"。逻辑运算符的操作数只能为Boolean。
4.4 关系运算符
Aviator支持的关系运算符包括"<" “<=” “>” “>=” 以及"==“和”!=" 。
&&和||都执行短路规则。
关系运算符可以作用于Number之间、String之间、Pattern之间、Boolean之间、变量之间以及其他类型与nil之间的关系比较,不同类型除了nil之外不能相互比较。
Aviator规定任何对象都比nil大除了nil之外。
4.5 匹配运算符
匹配运算符"=~"用于String和Pattern的匹配,它的左操作数必须为String,右操作数必须为Pattern。
匹配成功后,Pattern的分组将存于变量$num,num为分组索引。
4.6 三元运算符
两种模式
默认AviatorEvaluator以编译速度优先:
AviatorEvaluator.setOptimize(AviatorEvaluator.COMPILE);
你可以修改为运行速度优先,这会做更多的编译优化:
AviatorEvaluator.setOptimize(AviatorEvaluator.EVAL);
Aviator 规则引擎介绍相关推荐
- java 规则引擎roolie_【智能决策引擎】规则引擎介绍
什么是决策? 决策指的是业务人员与决策人员制定的业务规则. 举个简单的例子:某商场节假日推出商品促销活动,凡购买满200元即可减50元,满300减100元 这就是一个决策. 规则引擎的由来 规则引擎是 ...
- 【智能决策引擎】规则引擎介绍
什么是决策? 决策指的是业务人员与决策人员制定的业务规则. 举个简单的例子:某商场节假日推出商品促销活动,凡购买满200元即可减50元,满300减100元 这就是一个决策. 规则引擎的由来 规则引擎是 ...
- QLExpress规则引擎介绍
规则引擎定义 根据数据来匹配对应的条件,并执行规则匹配后的动作系统.如果满足某些条件,就执行相关动作. 好处 可以帮助我们把多变的业务决策部分同其他业务逻辑隔离开,是的业务人员能够自行定制业务逻辑,无 ...
- 常见的规则引擎(Drools,RuleBook,Easy Rules等)对比
参考文章: https://www.jianshu.com/p/96cd60059aae 规则引擎调研 - 人在江湖之诗和远方 - 博客园 java开源规则引擎比较_常用规则引擎比较分析_学校砍了我的 ...
- springboot中使用规则引擎Drools
文章目录 规则引擎的场景 规则引擎介绍 使用规则引擎的优势 规则引擎应用场景 rools介绍 Drools入门案例 规则引擎构成 Drools基础语法 springboot使用规则引擎 规则引擎的场景 ...
- Golang 规则引擎原理及实战
本文主要介绍规则引擎在 golang 中的使用,将首先介绍 golang 中主要的规则引擎框架,然后利用 golang 原生的 parser 搭建一个简单的规则引擎实现基本的 bool 表达式解析工作 ...
- 规则引擎Drools在贷后催收业务中的应用
作者:vivo 互联网服务器团队- Feng Xiang 在日常业务开发工作中我们经常会遇到一些根据业务规则做决策的场景.为了让开发人员从大量的规则代码的开发维护中释放出来,把规则的维护和生成交由业务 ...
- 规则引擎的介绍与Drools的流程分析
规则引擎(RuleEngine)是一个有限状态机,通过入参实现状态转移,在Java中定义为JSR94规范.规则引擎目前的开源实现主要是JBoss家族的Drools,采用友好的Apache协议(意味着可 ...
- 规则引擎Drools详细介绍
规则引擎Drools详细介绍 一. 规则引擎概述 1.1 什么是规则引擎 1.2 使用规则引擎的优势 1.3 规则引擎应用场景 1.4 Drools介绍 二. Drools使用与说明 2.1 Droo ...
最新文章
- 您应该知道Python 3.10中的新特性!
- 搜索引擎设计实用教程(2)-以百度为例
- 47 -算法 -回文串 -Leetcode 125 - 验证回文串
- 过来人谈谈计算机考研复试
- (转)android连网详解
- Presentation Prompter for Mac(屏幕提词器)
- nosql数据库之Redis集群
- oracle 函数的使用
- SM3算法的编程实现
- c语言输出最大的数ns流程图_怎么将100至200中全部的素数用NS流程 – 手机爱问...
- c语言简单的图案设计,分形艺术图案设计
- Windows7旗舰版SP1_32位2018.10(纯净版)
- 《炬丰科技-半导体工艺》采用湿法工艺制备的具有自洁表面的黑硅
- Cloud Rush—聚是一团火
- 动态页面抓取超级指南_减少页面重量的完整指南
- flask项目中出现Error: While importing ‘manager‘, an ImportError was raised.
- 有用的一些链接Powerstore VxRail
- c语言学生信息结构体录入文件,C语言—学生信息管理系统
- 51单片机c语言常用语句详解,51单片机之C语言-4.5基本语句之条件选择语句
- 《热风》愿中国青年都摆脱冷气 摘抄记录
热门文章
- print python excel分隔_办公自动化 Python 小工具,对Excel文件,按某一列拆分成多个Excel文件或sheet...
- 微信公众号,接口服务配置url验证失败的问题
- 基于人脸识别的face识别在医疗中的应用
- Composer update 提示unable to use a proxy,malformed http_proxy
- 学习笔记 - CFA 权益
- 操作系统实验一·创建进程
- 【毕设狗】【单片机毕业设计】基于单片机的超声波测距系统的设计
- Boke and Tsukkomi——一般图匹配+带花树算法
- 技术干货 | pytest 自动化测试实战展示
- IOC和工厂模式的区别