Google Aviator表达式引擎

1、介绍

Aviator是一个用于动态表达式求值的高性能、轻量级Java引擎。以下是一些关于Aviator引擎的重要特点和设计目标:

轻量级和高性能: Aviator的设计目标之一是轻量级和高性能。它的大小很小,加上依赖包也很小,这有助于将其轻松集成到各种Java应用程序中。与某些重量级的脚本语言(如Groovy)相比,Aviator非常紧凑,因此适用于对性能要求较高的应用程序。
编译执行方式: Aviator与许多其他表达式引擎的不同之处在于,它不是通过解释表达式来执行,而是将表达式编译成Java字节码,然后将其交给Java虚拟机(JVM)执行。这种编译执行方式通常比解释执行更快。
受限的语法: Aviator的语法是有限的,它并不是一门完整的编程语言,而只是专注于表达式求值的一小部分。这种受限的语法使其易于学习和使用。
支持运算操作符: Aviator支持大部分运算操作符,包括算术操作符、关系运算符、逻辑操作符、位运算符、正则匹配操作符(=~)、三元表达式(?:)等。它还支持操作符的优先级和括号强制优先级。
自定义函数支持: Aviator允许用户定义自己的函数,这样您可以将自定义逻辑集成到表达式中,以满足特定的需求。

Aviator的实现思路与许多其他轻量级表达式求值器不同。它采用编译执行方式,将表达式直接编译成Java字节码,然后由Java虚拟机(JVM)执行。这种实现方式在性能上通常比解释执行更快。

其他轻量级表达式求值器通常采用解释执行方式,即通过分析和解释表达式字符串来执行计算。这使得它们更灵活,但也导致了性能开销较大。而Aviator的编译执行方式可以将表达式在执行前编译成字节码,这有助于提高性能,特别是对于需要频繁执行相同表达式的应用。

总的来说,Aviator的设计目标是提供一个介于重量级脚本语言(如Groovy)和轻量级表达式引擎(如IKExpression)之间的解决方案,它强调高性能和轻量级特性。这使得Aviator适用于那些需要快速、高效执行动态表达式求值的应用场景。

Aviator、IKExpression、QLExpress比较和建议
Aviator:

特点: 高性能:采用编译执行方式,将表达式编译成Java字节码,执行速度较快。轻量级:小巧的库,适用于需要高性能的应用。支持大部分运算操作符和自定义函数。语法相对受限,主要用于表达式求值。
使用建议: 当您需要在高性能环境中执行动态表达式,特别是需要频繁执行相同表达式的情况时,Aviator是一个不错的选择。如果您的主要需求是进行数学计算、条件检查或表达式求值,Aviator可以提供快速的执行。

IKExpression:

特点: 轻量级:IKExpression是一款轻量级的表达式引擎,适用于小型应用和嵌入式系统。
基于解释执行方式,相对较慢。支持常见的运算操作符和一些内置函数。语法相对简单,适合基本表达式求值。
使用建议:当您需要在轻量级Java应用或嵌入式系统中执行简单的动态表达式时,IKExpression是一个合适的选择。不适合需要高性能执行的大型应用程序或复杂的表达式。

QLExpress:

特点: 基于Java的表达式引擎,支持类似SQL的语法。较高的性能,使用JIT编译等技术进行优化。
支持条件检查、数据过滤和复杂计算。提供了类似SQL的语法,适合复杂表达式需求。
使用功建议:当您需要在Java应用程序中执行类似SQL的复杂动态表达式,或需要进行数据过滤和复杂计算时,QLExpress是一个很好的选择。适用于性能要求较高且需要执行复杂表达式的应用。

总体建议:

  • 如果需要高性能的轻量级表达式引擎,Aviator是一个不错的选择。
  • 如果需要在小型或嵌入式应用中执行简单的表达式,IKExpression可能更适合。
  • 对于需要执行复杂表达式和条件检查的应用,QLExpress是一个强大的工具。

选择应取决于项目的具体需求、性能要求和规模。如果可能,可以根据具体情况尝试不同的引擎以找到最适合项目的解决方案。

2、引入依赖

<dependencies>
        <dependency>
            <groupId>com.googlecode.aviator</groupId>
            <artifactId>aviator</artifactId>
            <version>5.3.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
           <!-- <scope>test</scope>-->
        </dependency>
    </dependencies>

3、demo测试

3.1、简单的使用
    @Test
    public void test1() {
        //发送规则表达式
        String expression = "(age > 35 && age < 75) && avgYear > 10000 && level == 1";
        //编译表达式
        Expression compileExp = AviatorEvaluator.compile(expression);
        //设置变量
        Map<String, Object> map = new HashMap<>();
        map.put("age", 40);
        map.put("level", 2);
        map.put("avgYear", 20000);
        //执行表达式
        System.out.println(compileExp.execute(map));//结果: false
    }

	//表达式传值
	@Test
    public void test(){
        //表达式传值
        Map<String, Object> env = new HashMap<>();
        env.put("name", "world");
        String str = "'hello ' + name";
        String r  = (String) AviatorEvaluator.execute(str, env);
        System.out.println(r);//hello world
    }
	
	@Test
    public void test3(){
        //算数表达式
        Long sum = (Long) AviatorEvaluator.execute("1 + 2 + 3");
        System.out.println(sum);//6
        //逻辑表达式
        boolean result = (boolean) AviatorEvaluator.execute("3 > 1");
        System.out.println(result);//true
        String r1  = (String) AviatorEvaluator.execute("100 > 80 ? 'yes' : 'no'");
        System.out.println(r1);//yes
    }

	//函数调用
	 @Test
    public void function() {
        //函数调用
        Long r2  = (Long) AviatorEvaluator.execute("string.length('hello')");
        System.out.println(r2);//5
        //调用自定义函数
        //注册函数
        AviatorEvaluator.addFunction(new CustomFunction());
        //调用函数
        System.out.println(AviatorEvaluator.execute("add(2,3)"));//5.0
        //删除函数
        //AviatorEvaluator.removeFunction("multi");
    }
3.2、规则引擎
public class AviatorExampleTwo {

    //规则可以保存在数据库中,mysql或者redis等等
    Map<Integer, String> ruleMap = new HashMap<>();
    public AviatorExampleTwo() {
        //秒数计算公式
        ruleMap.put(1, "hour * 3600 + minute * 60 + second");
        //正方体体积计算公式
        ruleMap.put(2, "height * width * length");
        //判断一个人是不是资深顾客
        ruleMap.put(3, "age >= 18 && sumConsume > 2000 && vip");
        //资深顾客要求修改
        ruleMap.put(4, "age > 10 && sumConsume >= 8000 && vip && avgYearConsume >= 1000");
        //判断一个人的年龄是不是大于等于18岁
        ruleMap.put(5, "age  >= 18 ? 'yes' : 'no'");
    }

    public Object getResult(int ruleId, Object... args) {
        String rule = ruleMap.get(ruleId);
        return AviatorEvaluator.exec(rule, args);
    }
    
    public static void main(String[] args) {
        AviatorExampleTwo aviatorExample = new AviatorExampleTwo();
        //选择规则,传入规则所需要的参数
        System.out.println("公式1:" + aviatorExample.getResult(1, 1, 1, 1));
        System.out.println("公式2:" + aviatorExample.getResult(2, 3, 3, 3));
        System.out.println("公式3:" + aviatorExample.getResult(3, 20, 3000, false));
        System.out.println("公式4:" + aviatorExample.getResult(4, 23, 8000, true, 2000));
        System.out.println("公式5:" + aviatorExample.getResult(5, 12));
    }
}

4、定义函数

4.1、add函数
public class CustomFunction extends AbstractFunction {
    @Override
    public String getName() {
        return "add";
    }
    @Override
    public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
        Number left = FunctionUtils.getNumberValue(arg1, env);
        Number right = FunctionUtils.getNumberValue(arg2, env);
        return new AviatorDouble(left.doubleValue() + right.doubleValue());
    }
}

  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值