MVEL 简单介绍
程序员文章站
2023-12-29 15:03:28
...
MVEL是一种基于java语法的表达式语言,为java提供更便捷灵活的动态性。
这里简单介绍一些MVEL的操作:
new 创建一个java对象,new String("foo"),当然这里是举个栗子,String的创建一般是不同这个构造函数的。
对于java.lang.*中的类,无需手动导入。如果是创建自定义的对象,就需要写明类全路径名,或者手动导入。
当需要针对同一个对象进行多次操作时,可以是with语句块来高效操作,
with(user = new User()) {
name = 'jacker',age = 18,sex = Sex.FEMALE
}
更便捷是可以使用点号操作
user = new User().{
name="jack";
parent = new User().{
name = "jack\'s parent";
}
}
动态脚本的一个头痛问题就是变量的作用域问题,经常在调试的时候发现一个局部变量覆盖了全局变量导致程序出错。
mvel提供 isdef 来判断某个变量在当前作用域内是否已经定义。defined = isdef var; 或者 if (isdef var) { doSomething();}
MVEL对正则表达式匹配做了简化,只需要通过 ~= 操作符判断即可,if(var ~= '[a-z].+') {doSomething();}
对集合的一些操作也进行了简化,var contains 'test' 判断var集合中是否包含'test'字符串,var可以是一个array,list或者map,
map的话就是判断keyset中是否包含指定的值。var也可以为string,在MVEL中string被认为是一个数组。
支持 in 操作符对list进行遍历,names = (name in users) 上面的操作可以很快的得到 users集合中每个元素的name属性。
同样支持调用集合中元素的方法(静态方法或者实例方法),(sayHello() in users) ,另外可以在子句后面加上if判断对list中
的元素过滤。 $ 用作占位符,($ in users if $.name contains 'jack')
==操作与java中的不用,MVEL中的使用equals()方法判断的。
list 创建
["Jim", "Bob", "Smith"]
map 创建
['Bob' : new Person('Bob'), 'Michael' : new Person('Michael')]
Array 创建
{"Jim", "Bob", "Smith"}
同时支持 lambda 表达式
threshold = def (x) { x >= 10 ? x : 0 }; result = cost + threshold(lowerBound);
更多的详细内容可以参考MVEL Language Guide
http://mvel.codehaus.org/Language+Guide+for+2.0
下面介绍一下例子:
表达式的执行有两种模式
一种是编译模式,就是先编译表达式并缓存,执行的时候传入对应的参数
一种是解析模式,跟其他脚本语言一样,边解析边执行
编译模式
解析模式
调用脚本文件中的函数
test.el 文件内容
def add(a,b){
a + b;
}
这里简单介绍一些MVEL的操作:
new 创建一个java对象,new String("foo"),当然这里是举个栗子,String的创建一般是不同这个构造函数的。
对于java.lang.*中的类,无需手动导入。如果是创建自定义的对象,就需要写明类全路径名,或者手动导入。
当需要针对同一个对象进行多次操作时,可以是with语句块来高效操作,
with(user = new User()) {
name = 'jacker',age = 18,sex = Sex.FEMALE
}
更便捷是可以使用点号操作
user = new User().{
name="jack";
parent = new User().{
name = "jack\'s parent";
}
}
动态脚本的一个头痛问题就是变量的作用域问题,经常在调试的时候发现一个局部变量覆盖了全局变量导致程序出错。
mvel提供 isdef 来判断某个变量在当前作用域内是否已经定义。defined = isdef var; 或者 if (isdef var) { doSomething();}
MVEL对正则表达式匹配做了简化,只需要通过 ~= 操作符判断即可,if(var ~= '[a-z].+') {doSomething();}
对集合的一些操作也进行了简化,var contains 'test' 判断var集合中是否包含'test'字符串,var可以是一个array,list或者map,
map的话就是判断keyset中是否包含指定的值。var也可以为string,在MVEL中string被认为是一个数组。
支持 in 操作符对list进行遍历,names = (name in users) 上面的操作可以很快的得到 users集合中每个元素的name属性。
同样支持调用集合中元素的方法(静态方法或者实例方法),(sayHello() in users) ,另外可以在子句后面加上if判断对list中
的元素过滤。 $ 用作占位符,($ in users if $.name contains 'jack')
==操作与java中的不用,MVEL中的使用equals()方法判断的。
list 创建
["Jim", "Bob", "Smith"]
map 创建
['Bob' : new Person('Bob'), 'Michael' : new Person('Michael')]
Array 创建
{"Jim", "Bob", "Smith"}
同时支持 lambda 表达式
threshold = def (x) { x >= 10 ? x : 0 }; result = cost + threshold(lowerBound);
更多的详细内容可以参考MVEL Language Guide
http://mvel.codehaus.org/Language+Guide+for+2.0
下面介绍一下例子:
表达式的执行有两种模式
一种是编译模式,就是先编译表达式并缓存,执行的时候传入对应的参数
一种是解析模式,跟其他脚本语言一样,边解析边执行
编译模式
ExpressionCompiler compiler = new ExpressionCompiler("x + y"); CompiledExpression exp = compiler.compile(); Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 10); params.put("y", 20); Object result = MVEL.executeExpression(exp, params); System.out.println(result);
解析模式
Map<String, Object> params = new HashMap<String, Object>(); params.put("x", 10); params.put("y", 20); Object result = MVEL.eval("x+y", params); System.out.println(result);
调用脚本文件中的函数
File scriptFile = new File("src/main/java/com/test/mvel/test.el"); VariableResolverFactory resolverFactory = new MapVariableResolverFactory(); MVEL.evalFile(scriptFile, ParserContext.create(), resolverFactory); resolverFactory.createVariable("x", 10); resolverFactory.createVariable("y", 20); Object result = MVEL.eval("add(x,y);", resolverFactory); System.out.println(result);
test.el 文件内容
引用
def add(a,b){
a + b;
}