AVIATOR——轻量级JAVA表达式求值引擎

目录

一:简介

二:特性

三:Aviator的限制

四:详细见官网 

五:案例大全

案例一

案例二

案例三

案例四 

案例五

案例六

案例七


一:简介

Aviator是一个高性能、轻量级的java语言实现的表达式求值引擎,主要用于各种表达式的动态求值。现在已经有很多开源可用的java表达式求值引擎,为什么还需要Avaitor呢?

Aviator的设计目标是*轻量级*和*高性能 ,相比于Groovy、JRuby的笨重,Aviator非常小,加上依赖包也才450K,不算依赖包的话只有70K;当然,Aviator的语法是受限的,它不是一门完整的语言,而只是语言的一小部分集合。

其次,Aviator的实现思路与其他轻量级的求值器很不相同,其他求值器一般都是通过解释的方式运行,而Aviator则是直接将表达式*编译成Java字节码,交给JVM去执行。简单来说,Aviator的定位是介于Groovy这样的重量级脚本语言和IKExpression这样的轻量级表达式引擎之间。

二:特性

Aviator的特性

  • 支持大部分运算操作符,包括算术操作符、关系运算符、逻辑操作符、位运算符、正则匹配操作符(=~)、三元表达式?: ,并且支持操作符的优先级和括号强制优先级,具体请看后面的操作符列表。

  • 支持大整数和精度运算(2.3.0版本引入)

  • 支持函数调用和自定义函数

  • 内置支持正则表达式匹配,类似Ruby、Perl的匹配语法,并且支持类Ruby的$digit指向匹配分组。

  • 自动类型转换,当执行操作的时候,会自动判断操作数类型并做相应转换,无法转换即抛异常。

  • 支持传入变量,支持类似a.b.c的嵌套变量访问。

  • 函数式风格的seq库,操作集合和数组

  • 性能优秀

三:Aviator的限制

  • 没有if else、do while等语句,没有赋值语句,仅支持逻辑表达式、算术表达式、三元表达式和正则匹配。

  • 不支持八进制数字字面量,仅支持十进制和十六进制数字字面量。

四:详细见官网 

AviatorScript 编程指南(5.0) · 语雀

五:案例大全

案例一

public static void main(String[] args) {
    // 表达式
    String expression = "a-(b-c) > 100";
    // 通过compile方法可以将表达式编译成Expression的中间对象
    Expression compiledExp = AviatorEvaluator.compile(expression,Boolean.TRUE);
    // compiledExp.newEnv(); 相当于创建了一个Map并赋值
    Boolean result = (Boolean) compiledExp.execute(compiledExp.newEnv("a", 100.3, "b", 45, "c", -199.100));
    System.out.println(result);// false
  }

 案例二

public static void main(String[] args) {
    // 创建解释器
    AviatorEvaluatorInstance engine = AviatorEvaluator.newInstance(EvalMode.INTERPRETER);
    // 打开跟踪执行(线上不建议开启)
    engine.setOption(Options.TRACE_EVAL, true);
    Expression exp = engine.compile("score > 80 ? 'good' : 'bad'");
    System.out.println(exp.execute(exp.newEnv("score", 100)));// good
    System.out.println(exp.execute(exp.newEnv("score", 50)));// bad
  }

案例三

public static void main(String[] args) {
    Map<String,Object> map = MapUtil.newHashMap();
    map.put("aa","美国,中国,德国,法国");
    map.put("bb","中国");
    // aa的数据是否包含bb
    Expression expression = AviatorEvaluator.compile("string.contains(aa,bb)", true);
    Boolean result = (Boolean) expression.execute(map);
    System.out.println("结果"+result);// 结果true
  }

案例四 

public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException {
    AviatorEvaluator.addStaticFunctions("str", CharSequenceUtil.class);
    Map<String,Object> map = MapUtil.newHashMap();
    map.put("aa","美国,中国,德国,法国");
    Expression expression = AviatorEvaluator.compile("str.isBlank(aa)", true);
    Boolean result = (Boolean) expression.execute(map);
    System.out.println("结果"+result);// 结果false
  }

案例五

public static void main(String[] args) {
    // site和receiveCountry可以先进行占位
    String expression = "string.contains('A,B,C',site)  && string.contains('AA,AC,CC,DD',receiveCountry)";
    // 编译表达式
    Expression compiledExp = AviatorEvaluator.compile(expression);
    Map<String, Object> env = new HashMap<>();
    env.put("site", "A");
    env.put("receiveCountry", "AA");
    // 执行表达式
    System.out.println( compiledExp.execute(env));// true
  }

 案例六

public class MoreStrFunction extends AbstractFunction {
  @Override
  public AviatorBoolean call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
    // 解析到“helllo-word”
    String original = FunctionUtils.getStringValue(arg1, env);
    // 解析到word
    String param = FunctionUtils.getStringValue(arg2, env);
    if (CharSequenceUtil.isBlank(param)){
      return AviatorBoolean.valueOf(Boolean.FALSE);
    }
    List<String> originals= CharSequenceUtil.split(original, StrPool.COMMA);
    List<String> params= CharSequenceUtil.split(param, StrPool.COMMA);
    return AviatorBoolean.valueOf(originals.containsAll(params));
  }
  @Override
  public String getName() {
    return "moreStrCompare";
  }
}



public static void main(String[] args) {
    String expression="moreStrCompare('hello-word',str)";
    AviatorEvaluator.addFunction(new MoreStrFunction());
    Expression compiledExp = AviatorEvaluator.compile(expression);
    //匹配
    Map<String, Object> env = new HashMap<>();
    env.put("str", "word");
    System.out.println(compiledExp.execute(env));// false
  }

案例七

public static void main(String[] args) {
    String expression="moreStrCompare('hello',site)  && string.contains('us,um',receiveCountry)  && weight>=0.01 && weight<=4.0 && moreStrCompare('测试',orderTag)  && string.contains('1001',id) ";
    AviatorEvaluator.addFunction(new MoreStrFunction());
    Expression compiledExp = AviatorEvaluator.compile(expression,true);

    Map<String, Object> ruleBO=JSONUtil.toBean("{\"id\":3913695,\"site\":\"aaa\",\"receiveCountryIos\":\"aa\",\"receiveProvince\":\"aa\",\"postcode\":\"aa\",\"weight\":0.99," 
                    + "\"orderTag\":\"\",\"skuCode\":\"a,b\",\"spuId\":\"1,2,3,4,5\",\"transportType\":\"aaa\",\"orderAmount\":152.75}", Map.class);
    //匹配
    System.out.println(compiledExp.execute(ruleBO));//false
  }

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值