Aviator表达式求值引擎

一、简介:

Aviator是一个高性能、轻量级的java语言实现的表达式求值引擎,主要用于各 种表达式的动态求值。现在已经有很多开源可用的java表达式求值引擎,为什 么还需要Avaitor呢? Aviator的设计目标是轻量级和高性能 ,相比于Groovy、JRuby的笨重,Aviator 非常小,加上依赖包也才450K,不算依赖包的话只有70K;当然,Aviator的语法 是受限的,它不是一门完整的语言,而只是语言的一小部分集合。 其次,Aviator的实现思路与其他轻量级的求值器很不相同,其他求值器一般都 是通过解释的方式运行,而Aviator则是直接将表达式编译成Java字节码,交给 JVM去执行。简单来说,Aviator的定位是介于Groovy这样的重量级脚本语言和 IKExpression这样的轻量级表达式引擎之间。

二、特性:

支持大部分运算操作符,包括算术操作符、关系运算符、逻辑操作符、 正则匹配操作符(=~)、三元表达式?: ,并且支持操作符的优先级和括号强制优 先级,具体请看后面的操作符列表。 支持正则表达式匹配,类似Ruby、Perl的匹配语法,并且支持类Ruby的 $digit指向匹配分组。自动类型转换,当执行操作的时候,会自动判断操作数类 型并做相应转换,无法转换即抛异常。 支持传入变量,支持类似a.b.c的嵌套变量访问。 性能优秀。 Aviator的限制,没有if else、do while等语句,没有赋值语句,仅支持逻 辑表达式、算术表达式、三元表达式和正则匹配。没有位运算符

三、整体结构:

20210728202412.jpg

四、maven依赖:

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

五、常用函数

5.1、设置编译参数

//优化执行速度(默认)
AviatorEvaluator.setOption(Options.OPTIMIZE_LEVEL,AviatorEvaluator.EVAL);
//优化编译速度
AviatorEvaluator.setOption(Options.OPTIMIZE_LEVEL,AviatorEvaluator.COMPILE);

5.2、使用方式

//先编译后执行
Expression expression=AviatorEvaluator.compile("groupType=='1' && (appType=='dt' || appType=='pt') ? 'aaaa' :'2'",true);
Long now = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
   expression.execute(map);
}
System.out.println(String.format( "执行10000次,耗时:%s 毫秒",String.valueOf (System.currentTimeMillis() - now)));

---- 执行10000次,耗时:19 毫秒



//边编译边执行
Long now = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
    AviatorEvaluator.execute("groupType=='1' && (appType=='dt' || appType=='pt') ? 'aaaa' :''", map);
}
System.out.println(String.format( "执行10000次,耗时:%s 毫秒",String.valueOf (System.currentTimeMillis() - now)));

---- 执行10000次,耗时:3971 毫秒

先编译后执行的性能很高,可以用在高并发场景。

六、函数

6.1、内置函数

image (7).png image (8).png

/**
 * CreateBy: haleyliu
 * CreateDate: 2018/12/25
 */
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));

    }
}

6.2、自定义函数

自定义函数要继承AbstractFunction类,重写目标方法。

/**
 * CreateBy: haleyliu
 * CreateDate: 2018/12/25
 */
public class Test {
    public static void main(String[] args) {
        // 注册自定义函数
        AviatorEvaluator.addFunction(new MultiplyFunction());
        // 方式1
        System.out.println(AviatorEvaluator.execute("multiply(12.23, -2.3)"));
        // 方式2
        Map<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{
    @Override
    public 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);
    }

    @Override
    public String getName() {
        return "multiply";
    }

}

七、运算

7.1、操作符

image (9).png

7.2、常量和变量

image (10).png

7.3、数组和集合使用

/**
 * CreateBy: haleyliu
 * CreateDate: 2018/12/25
 */
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));

    }

}

7.4、三元比较符

/**
 * CreateBy: haleyliu
 * CreateDate: 2018/12/25
 */
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);
    }

}

7.5、正则表达式匹配

/**
 * CreateBy: haleyliu
 * CreateDate: 2018/12/25
 */
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);
    }
}

7.6、变量的语法糖衣

/**
 * 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);
    }
}


/**
 * CreateBy: haleyliu
 * CreateDate: 2018/12/25
 */
public class User {

    private int id;

    private String name;

    private String age;

    public User() {
    }

    public User(int id, String name, String age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

}

7.7、nil对象[任何对象都比nil大除了nil本身]

nil是Aviator内置的常量,类似java中的null,表示空的值。nil跟null不同的在
于,在java中null只能使用在==、!=的比较运算符,而nil还可以使用>、>=、
<、<=等比较运算符。Aviator规定,[任何对象都比nil大除了nil本身]。用户传入
的变量如果为null,将自动以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

7.8、日期比较

/**
 * CreateBy: haleyliu
 * CreateDate: 2018/12/25
 */
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);


    }
}

参考:https://www.jianshu.com/p/41ea7a43093c


已有 0 条评论

    欢迎您,新朋友,感谢参与互动!