*(00)*

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

原文:https://www.yuque.com/boyan-avfmj/aviatorscript

AviatorScript 文档

起源

 

Aviator 起源于 2010 年左右,当时我还在淘宝中间件,读了龙书,了解了 ASM ,开始读 clojure 编译器的源码。刚好同时在做 Notify 这个内部消息中间件的一个重要版本实现,其中有一个需求是实现 AMQP 规范里的 header 订阅,允许用户指定一个布尔表达式来决定是否订阅某种类型的消息,需要对布尔表达式字符串进行求值。当时正处于造轮子的兴奋期,因此就写了第一个版本出来,第一个版本花了一两天的功夫,整个代码结构其实到现在也没有特别大的改变,还是那么乱 :)

 

表达式引擎当时国内开源的已经有 IKExpression,可惜是纯解释执行的,效率很一般,Groovy 刚开始流行,性能不错,但是整体很重量级,更重要的原因是我们希望控制用户能使用的语法和函数,需要一个定制的“子集”,因此 Aviator 就诞生了。

 

后来这个库用到了很多公司的很多地方,并且不少场景都是出乎我的意料之外的,常见的公式计算不提,也有用在数据处理转换、数据核对以及工作流逻辑判定、鉴权校验等等。这也是我继续发展它的动力。

 

原理和特点

 

Aviator 的基本过程是将表达式直接翻译成对应的 java 字节码执行,整个过程最多扫两趟(开启执行优先模式,如果是编译优先模式下就一趟),这样就保证了它的性能超越绝大部分解释性的表达式引擎,测试也证明如此;其次,除了依赖  commons-beanutils 这个库之外(用于做反射)不依赖任何第三方库,因此整体非常轻量级,整个 jar 包大小哪怕发展到现在 5.0 这个大版本,也才 430K。同时, Aviator 内置的函数库非常“节制”,除了必须的字符串处理、数学函数和集合处理之外,类似文件 IO、网络等等你都是没法使用的,这样能保证运行期的安全,如果你需要这些高阶能力,可以通过开放的自定义函数来接入。因此总结它的特点是:

 

  • 高性能
  • 轻量级
  • 一些比较有特色的特点:
    • 支持运算符重载
    • 原生支持大整数和 BigDecimal 类型及运算,并且通过运算符重载和一般数字类型保持一致的运算方式。
    • 原生支持正则表达式类型及匹配运算符 =~ 
    • 类 clojure 的 seq 库及 lambda 支持,可以灵活地处理各种集合
  • 开放能力:包括自定义函数接入以及各种定制选项

 

AviatorScript:5.0

 

任何使用 5.x 版本的朋友,请升级到 5.2.6 及以上版本。

 

Aviator 原来的定位一直只是一个表达式引擎,不支持 if/else 条件语句(仅有三元运算符支持 ?: ),没有内置的 for/while 循环支持(虽然你可以用 seq 库类似函数式的方式来处理集合),也没有赋值(后来在 4.0 引入),没有作用域的概念(也在 4.0 引入 lambda 函数后部分实现)等等一般语言常见的能力。不过在 5.0 这个大版本(也就是本指南介绍的主要版本)将支持上述所有的能力,变成一门通用的脚本语言 AviatorScript

 

  • 词法作用域 {...} ,和 let 定义作用域内的变量
  • return 语句,用于从函数或者 script 中返回(值)。
  • if/elsif/else 条件语句
  • for/while 循环语句,以及 break / continue  支持
  • fn 语法用于定义命名函数, 4.0 已经引入了 lambda -> ... end 语法专门用于匿名函数定义
  • ## 单行注释 支持
  • 和 Java Scripting API 更好的集成
  • 字符串插值
  • 异常处理 try...catch...finally 语句等等。

 

没有改变的是:

  • 继续保持轻量化。
  • 还是 two pass 编译,最终生成 JVM 字节码,保证性能比一般解释型脚本快。
  • 内置函数继续“节制”,但是现在也有很灵活的方式来调用任何 Java 类的方法。
  • 几乎向前兼容,不兼容的地方很少,我们将在发布版本里说明。

 

为什么还要有 aviator ?

这是有人向我提出来的问题,既然 groovy/kotlin/jruby 都发展的这么好,还有没有必要发展 AviatorScript?我直接用他们不也是挺好的。

 

我的答案是没错,优先使用社区广泛使用的语言,有一个比较好的社区支持,这都是很好、很正确的考量。那么为什么还想要发展和去使用 AviatorScript? 我能想到的理由如下:

 

  • 我可以,并且我将继续维护它
  • 你不想使用一个全功能的、相对重量级的语言,你只是做一些布尔表达式判定、数据集合处理等等,你不想引入一堆依赖,并且期待有一定的性能保证。AviatorScript 提供了大量的定制选项,甚至各种语法特性都是可以开关的。
  • 你的表达式或者 script 是用户输入的,你无法保证他们的安全性,你希望控制用户能使用的 API,提供一个相对安全的运行沙箱
  • 你原来的项目在使用 aviator,有一堆遗留的表达式要维护,原来没有很好的条件语句、循环语句等能力支持,让你的使用受限了。
  • 你就是喜欢 AviatorScript 的语法
  • 你就是想用它

 

老版本如何升级到 5.0 大版本?

请阅读文档《如何升级到 5.0 大版本(老用户必读)》

 

感谢所有用户的支持,有问题可以随时到 github 反馈

 

 

posted on 2022-07-28 09:34  *(00)*  阅读(1990)  评论(0编辑  收藏  举报