一、简单认识Aviator:
Aviator是一个高性能、轻量级的 java 语言实现的表达式求值引擎,它动态地将表达式编译成字节码并运行,主要用于各种表达式的动态求值。
Aviator的优点:
Aviator的设计目标是轻量级和高性能,相比于Groovy、JRuby的笨重,Aviator非常小。当然,Aviator的语法是受限的,它不是一门完整的语言,而只是语言的一小部分集合。
Aviator的实现思路与其他轻量级的求值器很不相同,其他求值器一般都是通过解释的方式运行,而Aviator则是直接将表达式编译成 JVM 字节码,交给 JVM 去执行。简单来说,Aviator的定位是介于 Groovy 这样的重量级脚本语言和 IKExpression 这样的轻量级表达式引擎之间。
Aviator的特性:
1.支持绝大多数运算操作符,包括算术操作符、关系运算符、逻辑操作符、位运算符、正则匹配操作符(=~)、三元表达式(?: )。
2.支持操作符优先级和括号强制设定优先级。
3.逻辑运算符支持短路运算。
4.支持丰富类型,例如nil、整数和浮点数、字符串、正则表达式、日期、变量等,支持自动类型转换。
5.内置一套强大的常用函数库。
6.可自定义函数,易于扩展。
7.可重载操作符。
8.支持大数运算(BigInteger)和高精度运算(BigDecimal)。
9.性能优秀。
二、Aviator的使用:
包依赖:
com.googlecode.aviatorgroupId>
aviatorartifactId>
3.3.0version>
dependency>
具体使用代码:
Aviator的使用都是集中通过com.googlecode.aviator.AviatorEvaluator这个入口类来处理。
1.常用方法:
// 输出的是6.8
System.out.println(AviatorEvaluator.execute("1 + 2.8 + 3"));
String name = "鹿骁俸";
Map env = Maps.newHashMap();
env.put("name", name);
// 输出的是你的名字是:鹿骁俸
System.out.println(AviatorEvaluator.execute("'你的名字是:' + name", env));
// Aviator 2.2 开始新增加一个exec方法, 可以更方便地传入变量并执行, 而不需要构造env这个map了
System.out.println(AviatorEvaluator.exec("'你的名字是:' + name", name));
env.put("a", 5);
env.put("b", 4);
// 输出的是6.333333333333333
System.out.println(AviatorEvaluator.execute("a + b / 3.0", env));
// 推荐的使用方式
System.out.println(AviatorEvaluator.compile("a + b / 3.0").execute(env));
2.字符串与转义符:
// 输出的是a"b
System.out.println(AviatorEvaluator.execute("'a\"b'"));
// 输出的是a'b
System.out.println(AviatorEvaluator.execute("\"a\'b\""));
// 输出的是hello 8
System.out.println(AviatorEvaluator.execute("'hello ' + 8"));
// 输出的是hello null
System.out.println(AviatorEvaluator.execute("'hello ' + unknow"));
3.函数调用及自定义函数:
@Test
public void test() {
// 输出的是5
System.out.println(AviatorEvaluator.execute("string.length('hello')"));
// 输出的是true
System.out.println(AviatorEvaluator.execute("string.contains(\"test\", string.substring('sword', 0, 1))"));
// 注册函数使用addFunction,移除函数使用removeFunction
AviatorEvaluator.addFunction(new AddFunction());
// 输出的是3.0
System.out.println(AviatorEvaluator.execute("add(1, 2)"));
// 输出的是103.0
System.out.println(AviatorEvaluator.execute("add(add(1, 2), 100)"));
}
class AddFunction extends AbstractFunction {
@Override
public AviatorObject call(Map env, AviatorObject arg1, AviatorObject arg2) {
Number left = FunctionUtils.getNumberValue(arg1, env);
Number right = FunctionUtils.getNumberValue(arg2, env);
return new AviatorDouble(left.doubleValue() + right.doubleValue());
}
public String getName() {
return "add";
}
}
4.编译表达式:
上面的例子大都是 Aviator 背后做了编译并执行的工作。其实可以先编译表达式,返回一个编译的结果,再传入不同的env来复用编译结果,提高性能,这是更推荐的使用方式。
String expression = "a - (b - c) > 100";
// 编译表达式
Expression compiledExp = AviatorEvaluator.compile(expression);
Map env = Maps.newHashMap();
env.put("a", 10