aviator使用示例

前言

提示:aviator的demo若干

简介

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

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

文档

aviator文档

maven

<dependency>
	<groupId>com.googlecode.aviator</groupId>
	<artifactId>aviator</artifactId>
	<version>5.3.0</version>
</dependency>

示例

import cn.hutool.crypto.digest.DigestUtil;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.AviatorEvaluatorInstance;
import com.googlecode.aviator.Expression;
import org.junit.Test;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

public class AviatorDemo {

    /**
     * 数值运算
     */
    @Test
    public void calculationTest() {
        // 模拟入参
        String aParam = "1.1";
        String bParam = "1.0";
        String cParam = "1.0";

        // 占位符
        String aStr = "arg[1]";
        String bStr = "arg[2]";
        String cStr = "arg[3]";

        // 占位符赋值
        String aValue = aStr.replace(aStr, aParam);
        String bValue = bStr.replace(bStr, bParam);
        String cValue = cStr.replace(cStr, cParam);

        // 脚本
        String script = "a / ( b + c )";
        Map<String, Object> map = new HashMap<>();

        // 入参
        map.put("a", new BigDecimal(aValue));
        map.put("b", new BigDecimal(bValue));
        map.put("c", new BigDecimal(cValue));

        AviatorEvaluatorInstance instance = AviatorEvaluator.getInstance();

        // 语法校验
        instance.validate(script);

        // 编译脚本 compile(final String cacheKey, final String expression, final boolean cached)
        //      参数
        //          cacheKey: cached 为 true 时,会缓存编译结果,默认缓存的 key 为 script,这里使用 md5 作为 key,这样 key 不会很长
        //          expression: 脚本
        //          cached: 设置为 true,否则都生成一个新的匿名类和对象,因此如果频繁调用会占满 JVM 的 metaspace,可能导致 full gc 或者 OOM
        Expression exp = instance.compile(DigestUtil.md5Hex(script), script, true);

        // 执行脚本
        BigDecimal result = (BigDecimal) exp.execute(map);

        System.err.println(result);
    }

    /**
     * 布尔表达式运算
     */
    @Test
    public void boolExpressionTest() {
        String script = "a / ( b + c ) == 5 && 3 == 3";
        Map<String, Object> map = new HashMap<>();
        map.put("a", 100);
        map.put("b", 10);
        map.put("c", 10);
        Expression exp = AviatorEvaluator.getInstance().compile(DigestUtil.md5Hex(script), script, true);
        Boolean bool = (Boolean) exp.execute(map);
        System.err.println(bool);
    }

    /**
     * 条件语句 if-else(支持复杂嵌套,注意: 若要使用 else if,需写成 elsif)
     */
    @Test
    public void conditionTest() {
        String script = "    if(a > b){                        " +
                "               return a - b;                  " +
                "            }else{                            " +
                "               return a + b;                  " +
                "            }                                 ";
        Map<String, Object> map = new HashMap<>();
        map.put("a", new BigDecimal("1.1"));
        map.put("b", new BigDecimal("1,0"));
        Expression exp = AviatorEvaluator.getInstance().compile(DigestUtil.md5Hex(script), script, true);
        Object execute = exp.execute(map);
        System.out.println(execute);
    }

    /**
     * for 循环
     */
    @Test
    public void forLoopTest() {
        String script = "for i in range(0, 10) {          " +
                "           if (i % 2 == 0) {             " +
                "               continue;                 " +
                "           }                             " +
                "           println(i);                   " +
                "        }                                ";
        Expression exp = AviatorEvaluator.getInstance().compile(DigestUtil.md5Hex(script), script, true);
        exp.execute();
    }

    /**
     * while 循环
     */
    @Test
    public void whileLoopTest() {
        String script = "while (a < 5 ) {       " +
                "           a = a + 1;          " +
                "           b = b * 10;         " +
                "        }                      " +
                "        return b;              ";
        Map<String, Object> map = new HashMap<>();
        map.put("a", new BigDecimal("1.1"));
        map.put("b", new BigDecimal("1.0"));
        Expression exp = AviatorEvaluator.getInstance().compile(DigestUtil.md5Hex(script), script, true);
        Object execute = exp.execute(map);
        System.out.println(execute);
    }

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值