Aviator 一种表达式求值引擎

Aviator是一个轻量级、高性能的Java表达式求值引擎,适用于动态计算。它采用编译成JVM字节码的方式运行,提供丰富的运算符、内置函数支持,以及自定义函数功能。Aviator的特性包括支持算术、逻辑、关系运算符,自动类型转换,变量嵌套访问等。此外,Aviator支持多行表达式、编译表达式以提高性能,并允许用户通过实现AviatorFunction接口自定义函数。尽管Aviator不提供if/else语句,但通过三元运算符可以实现类似功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.简介

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

2.特性

Aviator的特性:

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

Aviator的限制:

  • 没有if else、do while等语句,没有赋值语句,仅支持逻辑表达式、算术表达式、三元表达式和正则匹配。
  • 无法自定义运算符,自定义函数有局限性

3.依赖

Aviator依赖了commons-beanutils, 使用Aviator可以添加下面的maven依赖:

<dependency>
      <groupId>com.googlecode.aviator</groupId>
      <artifactId>aviator</artifactId>
      <version>{version}</version>
 </dependency>

从 3.2.0 版本开始, Aviator 仅支持 JDK 7 及其以上版本。 JDK 6 请使用 3.1.1 这个稳定版本。

4.使用手册

  1. 执行表达式
    Aviator的使用都是集中通过com.googlecode.aviator.AviatorEvaluator这个入口类来处理, 最简单的例子, 执行一个计算1+2+3的表达式:
val result = AviatorEvaluator.execute("1+2+3")
println(result)     //6

如果开启了 ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL 选项,那么在表达式中出现的浮点数都将解析为 BigDecimal,这是为了方便一些用户要求高精度的计算,又不想额外地给浮点数加上 M 后缀标记为 BigDecimal:

AviatorEvaluator.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true)
  1. 多行表达式
    从 4.0.0 开始, aviator支持以分号 ; 隔开的多行表达式,对于多行表达式求值的结果将是最后一个表达式的结果,例如
val result = AviatorEvaluator.execute("println('hello world'); 1+2+3 ; 100-1")
println(result) 
//输出结果:
//hello world
//99

表达式的结果将是最后一个表达式 100-1,也就是 99,但是中间的表达式也将执行,包括打印 hello world。通过在表达式求值过程中加入 println打印,可以方便调试,也可以通过 Options.TRACE_EVAL来跟踪执行过程,参见后续章节。

  1. 求值器多实例
    AviatorEvaluator是一个全局静态实例,但是很多场景下,你可能想为不同的场景提供一个不同的求值器实例,包括不同的选项配置和自定义函数列表等,那么从 4.0.0开始, Aviator提供了多实例的求值器支持:
val instance = AviatorEvaluator.newInstance
//接下来使用 instance,几乎跟 AviatorEvaluator 没有不同,只是换成了实例方法
  1. 使用变量
    下面的例子演示了怎么向表达式传入变量值, 表达式中的world是一个变量, 默认为null, 通过传入Map<String,Object>的变量绑定环境, 将world设置为“world”。 env 的key是变量名, value是变量的值。
val world = "world"
val env = new util.HashMap[String,Object]()
env.put("world",world)
val result =AviatorEvaluator.execute(" 'hello ' + world ",env)
println(result)        //  hello world

'hello ‘是一个Aviator的String, Aviator的String是任何用单引号或者双引号括起来的字符序列, String可以比较大小(基于unicode顺序), 可以参与正则匹配, 可以与任何对象相加, 任何对象与String相加结果为String。 String中也可以有转义字符,如\n、\、’ 等。

AviatorEvaluator.execute(" 'a\"b' ")                  // 字符串 a"b
AviatorEvaluator.execute(" \"a\'b\" ")                // 字符串 a'b
AviatorEvaluator.execute(" 'hello ' + 3 ")              // 字符串 hello 3
AviatorEvaluator.execute(" 'hello '+ unknow ")         // 字符串 hello null
  1. exec 方法
    Aviator 2.2 开始新增加一个exec方法, 可以更方便地传入变量并执行, 而不需要构造env这个map了:
val value = "world"
AviatorEvaluator.exec("'hello' + value",value)        //  hello world
  1. 调用函数
    Aviator 支持函数调用, 函数调用的风格类似 lua, 下面的例子获取字符串的长度:
AviatorEvaluator.execute("string.length('hello')") 

string.length(‘hello’)是一个函数调用, string.length是一个函数, 'hello’是调用的参数。
再用string.substring来截取字符串:

AviatorEvaluator.execute("string.contains(\"test\", string.substring('hello', 1, 2))") // true

通过string.substring(‘hello’, 1, 2)获取字符串’e’, 然后通过函数string.contains判断e是否在’test’中。可以看到, 函数可以嵌套调用。

  1. 自定义函数
    Aviator除了内置的函数之外,还允许用户自定义函数,只要实现com.googlecode.aviator.runtime.type.AviatorFunction接口, 并注册到AviatorEvaluator即可使用. AviatorFunction接口十分庞大, 通常来说你并不需要实现所有的方法, 只要根据你的方法的参数个数, 继承AbstractFunction类并override相应方法即可。
object test {
  def main(args: Array[String]): Unit = {
    Aviato
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值