表达式引擎是规则引擎的一部分,是一种嵌入在应用程序中的组件,实现了逻辑判断与程序代码中分离出来,并使用预定义的语义脚本编写业务条件。接受数据输入,解释执行表达式,并返回表达式执行结果。
在前面的文章中介绍了Aviator脚本引擎的实战,有感兴趣的小伙伴可以看下,在上一篇文章中主要介绍了,规则引擎的使用场景,以及市面上各个流行的规则引擎的技术调研与对比,其中也介绍了轻量级的规则引擎EasyRule,这个规则引擎,功能强大,执行效率很高,其运用的表达式解析引擎就是Mvel,Mvel的作者也是EasyRule的作者之一,本篇文章我们详细的介绍一下Mvel表达式引擎。
MVEL 基本语法与java语法有些类似,与java不同是MVEL是动态类型,可选分类,就是说在源文件中是没有类型限制的。一条MVEL表达式,简单的可以是单个标识符,复杂的则可能是一个充满了方法调用和内部集合创建的庞大的布尔表达式。
user.name 在这个表达式中,我们只是有一个标识符(user.name),这就是我们所说的MVEL的AA级属性表达式,该表达式可以获取一个变量或上下文对象的属性,通过这个表达式进行上下文对象赋值,取值条件判断等操作。属性表达式是MVEL的最常见的用途之一,通过它MVEL可以用来作为一个高性能,易使用的反射优化器。
MVEl对布尔表达式支持如:user.name == "Tom",与java语法一样,MVEL支持所有优先级规则,包括通过括号来控制执行顺序,如:(user.name == “Tom”) && ((user.age - 1) > 18)。
在一段脚本里,你可以写任意多个语句,语句的语法类似于java语法,可以进行条件判断,赋值,日志打印,数据返回等操作。
<!-- https://mvnrepository.com/artifact/org.mvel/mvel2 --> <dependency> <groupId>org.mvel</groupId> <artifactId>mvel2</artifactId> <version>2.4.14.Final</version> </dependency>
public class MvelScriptTest { @Test public void executeExpressionTest() { String expression = "1 + 2"; Object result = MVEL.eval(expression); System.out.println(result); } @Test public void executeExpressionMappingTest() { String expression = "a + b"; Map<String, Object> mapping = new HashMap<String, Object>(4); mapping.put("a", 1); mapping.put("b", 1); Object result = MVEL.eval(expression, mapping); System.out.println(result); } @Test public void executeScriptTest() { String script = "System.out.println(user.name);" + "if (user.name == \"Tom\") {" + "user.level = 2;" + "user.name = \"your name is \" + user.name;" + "}" + "return \"hello mvel\""; Map<String, Object> mapping = new HashMap<String, Object>(4); User user = new User(); user.setId(1); user.setName("Tom"); mapping.put("user", user); Object result = MVEL.eval(script, mapping); System.out.println("执行脚本的结果->" + result); System.out.println(user); } }
Mvel支持丰富的表达式语法,表达式引擎也是规则引擎的重要组成部分。在我们的系统中,可以结合着配置中心,动态、灵活的控制系统的规则条件,在一些paas系统中应用的场景比较丰富。Demo示例地址:script-engine: aviator表示引擎,mvel脚本引擎,java脚本引擎