1. AviatorScript介绍
AviatorScript
是一个高性能的规则引擎,并且提供了丰富的API来操作Java对象。
1.1 AviatorScript特点介绍
AviatorScript
具有以下特点:
- 高性能,
AviatorScript
可以将表达式直接翻译成为Java字节码执行; - 轻量级,整个
Aviator
包只有不到500K的大小,相较于传统的规则引擎比如Drools
、JRules
来说体积更小; - 支持数字(包括整型、浮点型、大整数都支持高精度运算)、字符串、布尔值等丰富的基本类型,可以使用所有的Java运算符进行运算;
- 支持正则表达式及运算符重载。
2. AviatorScript使用
2.1 引入依赖
<dependency> <groupId>com.googlecode.aviator</groupId> <artifactId>aviator</artifactId> <version>5.4.3</version></dependency>
2.2 编写代码
- 例子1
Expression compile = AviatorEvaluator.compile("print("hello aviator");");compile.execute();
//----------output----------hello aviator
通过以上代码就完成了第一个AviatorScript
脚本的运行。
- 例子2
接下来我们通过一段代码实现一个条件表达式的计算。
//编写规则脚本Expression compile = AviatorEvaluator.compile("x > y");Object execute = compile.execute(compile.newEnv("x",10,"y",13));System.out.println(execute);//----------output----------false
- 例子3
下面我们通过定义一个稍微复杂的条件表达式来实现自动的计算从而得到比较结果
Expression compile = AviatorEvaluator.compile("(a>0||c<1)&&(b>10)");Object execute = compile.execute(compile.newEnv("a", 0.3, "c", 10, "b", 10.2F));System.out.println(execute);//----------output----------true//执行过程://0.3 > 0 为 true//10.2 > 10 为true// true && true 结果也为true
通过以上三个例子可以看到Aviator可以通过调用compile()
方法传入对应的脚本文本,得到一个Expression
对象,最终会由这个对象去调用execute()
方法去进行运算得到结果,这个方法有个好处就是可以接收一个Map
对象来给脚本中的变量赋值,可以实现根据用户填报的条件给变量进行不同赋值获取动态的运算结果,这样就极大给我们省了很多的代码编写,条件的比较过程我们可以交给Aviator
来帮我们实现。同样的,我们也可以通过构建不同的Map
对象,复用Expression
对象,对一个表达式进行反复求值。下面在例子3
的基础上构建一个新的Map
对象,对同一个表达式进行多次求值,可以看到根据不同的赋值,得到不同的运算结果。
- 例子4
Expression compile = AviatorEvaluator.compile("(a>0||c<1)&&(b>10)");Object execute = compile.execute(compile.newEnv("a", 0.3, "c", 10, "b", 10.2F));System.out.println(execute);execute = compile.execute(compile.newEnv("a", 0, "c", 10, "b", 10.2F));System.out.println(execute);//----------output----------truefalse
在实际的开发场景中我们可能往往不会清楚的知道条件表达式中会有多少未初始化的变量,这个时候我们可以通过调用Expression
的getVariableNames()
方法。还是通过上面这个例子的条件表达式进行变量的打印来举例说明,
- 例子5
Expression compile = AviatorEvaluator.compile("(a>0||c<1)&&(b>10)");List<String> variableNames = compile.getVariableNames();variableNames.forEach(System.out::println);//----------output----------acb
AviatorScript
也支持对逻辑运算符&&
和||
起别名,在设置别名后原来的运算符也还可以继续使用。
- 例子6
AviatorEvaluatorInstance instance = AviatorEvaluator.getInstance();instance.aliasOperator(OperatorType.AND,"和");instance.aliasOperator(OperatorType.OR,"或");Expression compile = instance.compile("a + 1 > 10 和 a < 11");Map<String, Object> map = new HashMap<>();map.put("a",9.5D);Object execute = compile.execute(map);System.out.println(execute);compile = instance.compile("a + 1 > 10 && a < 11");map.put("a",9);System.out.println(compile.execute(map));//----------output----------truefalse
以上就是AviatorScript
的基本使用,除此之外AviatorScript
还支持很多其他的功能,比如:
- 对运算符进行重载:在某些场景中不支持除法运算,可以通过对运算符的重载,屏蔽
/
运算; - 异常捕获,在脚本内就可以在发生异常之后做出处理;
- 函数,在
例子1
中其实就已经使用过了print()
函数来打印字符串,也支持自定义函数等等。
3.应用场景
AviatorScript
通过灵活的表达式配置可以应用在规则判断、公式计算、动态脚本控制以及数据ETL场合中,也能够应用在一些边缘计算的场景,根据提前定义好的条件规则对数据进行提前一步的处理。AviatorScript
可以满足我们绝大多数场景下的使用需求,它非常的轻量,支持灵活的扩展,应用在项目中可以提高业务的灵活性,降低开发的工作量。