【JAVA】Aviator是一个高性能、轻量级的java语言实现的表达式求值引擎
一、介绍
Aviator是一个高性能、轻量级的java语言实现的表达式求值引擎,主要用于各种表达式的动态求值。Aviator相比于Groovy、JRuby的笨重,Aviator非常轻量。
#二、原理和特点
-
高性能:Aviator 的基本过程是将表达式直接翻译成对应的 java 字节码执行,整个过程最多扫两趟(开启执行优先模式,如果是编译优先模式下就一趟),这样就保证了它的性能超越绝大部分解释性的表达式引擎
-
轻量级:除了依赖
commons-``beanutils
这个库之外(用于做反射)不依赖任何第三方库,因此整体非常轻量级,整个 jar 包大小哪怕发展到现在 5.0 这个大版本,也才 430K -
一些比较有特色的特点:
-
- 支持运算符重载
-
- 原生支持大整数和 BigDecimal 类型及运算,并且通过运算符重载和一般数字类型保持一致的运算方式。
-
- 原生支持正则表达式类型及匹配运算符
=~
- 原生支持正则表达式类型及匹配运算符
-
- 类 clojure 的 seq 库及 lambda 支持,可以灵活地处理各种集合
-
开放能力:包括自定义函数接入以及各种定制选项
#三、Hello World
#1、Java使用
依赖引入
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>5.3.3</version>
</dependency>
案例
public class RunScriptExample {
public static void main(String[] args) throws IOException {
// Enable java method invocation by reflection.
AviatorEvaluator.getInstance()
.setFunctionMissing(JavaMethodReflectionFunctionMissing.getInstance());
// You can trry to test every script in examples folder by changing the file name.
Expression exp = AviatorEvaluator.getInstance().compileScript("/Users/10072656/IdeaProjects/spring-demo/src/main/java/com/example/springdemo/examples/hello.av");
exp.execute();
}
}
#2、编译和执行
#2.1、AviatorScript引擎
AviatorScript编译和执行的入口都是AviatorEvaluator
类,该类的一个实例就是一个编译和执行的单元,这个单元我们称为一个 AviatorScript 引擎,AviatorEvaluator.getInstance()
返回一个全局共享的 AviatorScript 引擎。
#2.2、编译脚本文件
用 compileScript(path)
方法编译一个脚本文件,这个方法对文件路径查找按照下列顺序:
- path 指定的文件系统绝对或者相对路径
user.dir
项目的根目录开始的相对路径- classpath 下的绝对和相对路径
找到就尝试读取脚本并动态实时地编译成 JVM 字节码,最终的结果是一个 Expression
对象,每次调用 compileScript(path)
都生成一个新的匿名类和对象,因此如果频繁调用会占满 JVM 的 metaspace,可以通过第二个参数决定是否缓冲:
Expression exp = AviatorEvaluator.getInstance().compileScript("examples/hello.av", true);
exp.execute();
#2.3、编译文本文件
如果我们脚步存储在其他地方,比如数据库、外部文件等,获取后得到的是一个String对象,我们可以使用comiple
方法来编译:
Expression compile = AviatorEvaluator.getInstance().compile("println('Hello, AviatorScript!');");
compile.execute();
#2.4、执行
编译产生的 Expression
对象,最终都是调用 execute()
方法执行,得到结果。但是 execute
方法还可以接受一个变量列表组成的 map,来注入执行的上下文,我们来一个例子:
public class RunAcExample {
public static void main(String[] args) {
String expression = "a + b > 100";
Expression compile = AviatorEvaluator.compile(expression);
Object execute = compile.execute(compile.newEnv("a", 80, "b", 70));
System.out.println(execute);
}
}
我们定义了一个表达式,但是这个表达式的参数具体数值没有指定,我们可以在执行的时候指定具体的数值。
#2.5、语法校验
AviatorEvaluator.validate("1 ++ 2");
#四、基本类型和语法
#1、基本类型及运算
#1.1、整数
整数例如 -99、0、1、2、100……等等,对应的类型是 java 中的 long 类型。AviatorScript 中并没有 byte/short/int 等类型,统一整数类型都为 long,支持的范围也跟 java 语言一样。
let a = 99;
let b = 0xFF;
let c = -99;
println(a + b);
println(a / b);
println(a- b + c);
println(a + b * c);
println(a- (b - c));
println(a/b * b + a % b);
public class Number {
public static void main(String[] args) throws IOException {
Expression expression = AviatorEvaluator.getInstance().compileScript("src/main/java/com/example/springdemo/examples/number_demo/number.av");
Object execute = expression.execute();
System.out.println(execute);
}
}
整数相除的结果仍然是整数,比如例子中的
**a/b**
结果就是 0,遵循 java 的整数运算规则。
#1.2、大整数
let a = 10223372036854774807; ## Literal BigInteger
let b = 1000N; ## BigInteger
let c = 1000; ## long type
println(a);
println(a + a);
println(a * a);
println(a + b + c);
#1.3、浮点数
数字除了整数之外,AviatorScript 同样支持浮点数,但是仅支持 double 类型,也就是双精度 64 位,符合 IEEE754 规范的浮点数。传入的 java float 也将转换为 double 类型。所有的浮点数都被认为是 double 类型。浮点数的表示形式有两种:
-
十进制的带小数点的数字,比如
1.34159265
,0.33333
等等。 -
科学计数法表示,如
1e-2
,2E3
等等,大小写字母e
皆可。
let a = 2;
let err = 1e-15;
let root = a;
while math.abs(a - root * root) &
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!