Aviator表达式求值引擎

Posted ESOO

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Aviator表达式求值引擎相关的知识,希望对你有一定的参考价值。

Aviator是一个轻量级、高性能的Java表达式执行引擎,它动态地将表达式编译成字节码并运行。

特性包括:

  1. 支持绝大多数运算操作符,包括算术操作符、关系运算符、逻辑操作符、位运算符、正则匹配操作符(=~)、三元表达式(?:)
  2. 支持操作符优先级和括号强制设定优先级
  3. 逻辑运算符支持短路运算。
  4. 支持丰富类型,例如nil、整数和浮点数、字符串、正则表达式、日期、变量等,支持自动类型转换。
  5. 内置一套强大的常用函数库
  6. 可自定义函数,易于扩展
  7. 可重载操作符
  8. 支持大数运算(BigInteger)和高精度运算(BigDecimal)
  9. 性能优秀

 

下面来正式使用:

先引入依赖

 

<dependency>
    <groupId>com.googlecode.aviator</groupId>
    <artifactId>aviator</artifactId>
    <version>3.3.0</version>
</dependency>

写个简单的用法,先来了解这个表达式:

 

package com.xzg.aviator;

import com.googlecode.aviator.AviatorEvaluator;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Administrator on 2018/5/22.
 *
 * @author XieZG
 * @date 2018/5/22
 */
public class TestCalc 
    public static void main(String[] args) 
        int[] a = new int[]6, 7, 8, 9;
        Map<String, Object> env = new HashMap<String, Object>();
        env.put("a", a);

        System.out.println(AviatorEvaluator.execute("1 + 2 + 3"));
        System.out.println(AviatorEvaluator.execute("a[1] + 100", env));
        System.out.println(AviatorEvaluator.execute("'a[1]=' + a[1]", env));
        //求数组长度
        System.out.println(AviatorEvaluator.execute("count(a)", env));
        //求数组总和
        System.out.println(AviatorEvaluator.execute("reduce(a, +, 0)", env));
        //检测数组每个元素都在 0 <= e < 10 之间。
        System.out.println(AviatorEvaluator.execute("seq.every(a, seq.and(seq.ge(0), seq.lt(10)))", env));
    

可以看到aviator支持运算,取值,还有一个内置函数可以用。有些童鞋可能不太了解,说这些直接写java程序也能做,为啥要用表达式。其实是有些场景需要使用它,比如风控系统,是要给业务配置表达式的,然后程序执行它,总不可能每次业务规则变更都要程序员来改吧。

而且aviator里还有reduce,sort等高阶函数,可以简化开发哦。

上面代码频繁使用了一个类com.googlecode.aviator.AviatorEvaluator,这个就是aviator表达式的入口类,所有表达式的使用都是通过这个类的。

 

然后再来个进阶的用法:

 

package com.xzg.aviator;

import com.googlecode.aviator.AviatorEvaluator;
import lombok.Data;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Administrator on 2018/5/22.
 *
 * @author XieZG
 * @date 2018/5/22
 */
public class TestAviator 
    private String aa="jack";

    public String getAa() 
        return aa;
    

    public void setAa(String aa) 
        this.aa = aa;
    

    public static void main(String[] args) 
        Map<String, Object> env = new HashMap<String, Object>();
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(3);
        list.add(20);
        list.add(10);
        env.put("list", list);
        env.put("email", "killme2008@gmail.com");
        env.put("test", new TestAviator());
        env.put("date",new Date());
        String username = (String) AviatorEvaluator.execute("email=~/([\\\\w0-8]+)@\\\\w+[\\\\.\\\\w+]+/ ? $1 : 'unknow' ", env);
        System.out.println(username);
        System.out.println(AviatorEvaluator.exec("a>0? 'yes':'no'", 1));
        System.out.println(AviatorEvaluator.execute("'test.aa ='+test.aa", env));
        System.out.println(AviatorEvaluator.execute(" obj==nil", env));
        System.out.println(AviatorEvaluator.execute(" date > '2018-05-21 00:00:00:00'", env));
        System.out.println(AviatorEvaluator.execute(" date > '2018-05-22 12:00:00:00'", env));

        Object result = AviatorEvaluator.execute("count(list)", env);
        System.out.println(result);  // 3
        result = AviatorEvaluator.execute("reduce(list,+,0)", env);
        System.out.println(result);  // 33
        result = AviatorEvaluator.execute("filter(list,seq.gt(9))", env);
        System.out.println(result);  // [10, 20]
        result = AviatorEvaluator.execute("include(list,10)", env);
        System.out.println(result);  // true
        result = AviatorEvaluator.execute("sort(list)", env);
        System.out.println(result);  // [3, 10, 20]
        AviatorEvaluator.execute("map(list,println)", env);
    

简单说下,里面有正则,三元,null判断,对象属性获取,还有一些集合函数。

其实aviator支持的函数还挺多的:

 

内置函数

函数名称说明
sysdate()返回当前日期对象 java.util.Date
rand()返回一个介于 0-1 的随机数,double 类型
rand(n)返回一个介于 0- n 的随机数,long 类型
print([out],obj)打印对象,如果指定 out,向 out 打印, 否则输出到控制台
println([out],obj)与 print 类似,但是在输出后换行
now()返回 System.currentTimeMillis
long(v)将值的类型转为 long
double(v)将值的类型转为 double
str(v)将值的类型转为 string
date_to_string(date,format)将 Date 对象转化化特定格式的字符串,2.1.1 新增
string_to_date(source,format)将特定格式的字符串转化为 Date 对 象,2.1.1 新增
string.contains(s1,s2)判断 s1 是否包含 s2,返回 Boolean
string.length(s)求字符串长度,返回 Long
string.startsWith(s1,s2)s1 是否以 s2 开始,返回 Boolean
string.endsWith(s1,s2)s1 是否以 s2 结尾,返回 Boolean
string.substring(s,begin[,end])截取字符串 s,从 begin 到 end,如果忽略 end 的话,将从 begin 到结尾,与 java.util.String.substring 一样。
string.indexOf(s1,s2)java 中的 s1.indexOf(s2),求 s2 在 s1 中 的起始索引位置,如果不存在为-1
string.split(target,regex,[limit])Java 里的 String.split 方法一致,2.1.1 新增函数
string.join(seq,seperator)将集合 seq 里的元素以 seperator 为间隔 连接起来形成字符串,2.1.1 新增函数
string.replace_first(s,regex,replacement)Java 里的 String.replaceFirst 方法, 2.1.1 新增
string.replace_all(s,regex,replacement)Java 里的 String.replaceAll 方法 , 2.1.1 新增
math.abs(d)求 d 的绝对值
math.sqrt(d)求 d 的平方根
math.pow(d1,d2)求 d1 的 d2 次方
math.log(d)求 d 的自然对数
math.log10(d)求 d 以 10 为底的对数
math.sin(d)正弦函数
math.cos(d)余弦函数
math.tan(d)正切函数
map(seq,fun)将函数 fun 作用到集合 seq 每个元素上, 返回新元素组成的集合
filter(seq,predicate)将谓词 predicate 作用在集合的每个元素 上,返回谓词为 true 的元素组成的集合
count(seq)返回集合大小
include(seq,element)判断 element 是否在集合 seq 中,返回 boolean 值
sort(seq)排序集合,仅对数组和 List 有效,返回排 序后的新集合
reduce(seq,fun,init)fun 接收两个参数,第一个是集合元素, 第二个是累积的函数,本函数用于将 fun 作用在集合每个元素和初始值上面,返回 最终的 init 值
seq.every(seq, fun)fun 接收集合的每个元素作为唯一参数,返回 true 或 false。当集合里的每个元素调用 fun 后都返回 true 的时候,整个调用结果为 true,否则为 false。
seq.not_any(seq, fun)fun 接收集合的每个元素作为唯一参数,返回 true 或 false。当集合里的每个元素调用 fun 后都返回 false 的时候,整个调用结果为 true,否则为 false。
seq.some(seq, fun)fun 接收集合的每个元素作为唯一参数,返回 true 或 false。当集合里的只要有一个元素调用 fun 后返回 true 的时候,整个调用结果立即为 true,否则为 false。
seq.eq(value)返回一个谓词,用来判断传入的参数是否跟 value 相等,用于 filter 函数,如filter(seq,seq.eq(3)) 过滤返回等于3 的元素组成的集合
seq.neq(value)与 seq.eq 类似,返回判断不等于的谓词
seq.gt(value)返回判断大于 value 的谓词
seq.ge(value)返回判断大于等于 value 的谓词
seq.lt(value)返回判断小于 value 的谓词
seq.le(value)返回判断小于等于 value 的谓词
seq.nil()返回判断是否为 nil 的谓词
seq.exists()返回判断不为 nil 的谓词
seq.and(p1, p2, p3, ...)组合多个谓词函数,返回一个新的谓词函数,当今仅当 p1、p2、p3 ...等所有函数都返回 true 的时候,新函数返回 true
seq.or(p1, p2, p3, ...)组合多个谓词函数,返回一个新的谓词函数,当 p1, p2, p3... 其中一个返回 true 的时候,新函数立即返回 true,否则返回 false。

以上是关于Aviator表达式求值引擎的主要内容,如果未能解决你的问题,请参考以下文章

aviator使用手册在线

Google Aviator——轻量级 Java 表达式引擎实战

规则表达式引擎框架

规则表达式引擎框架

google aviator:轻量级Java公式引擎

java规则引擎Aviator