Mvel使用指南

mvel的执行方式分为两种:一种解释执行和编译执行.解释模式是一个无状态的,动态解释执行。不像编译模式需要负载表达式,他不需要就可以执行相应的脚本。编译模式需要在缓存中产生一个完全规范化表达式之后再执行.表达式通常被称为speed-sensitive应用,第二个选项可能会更好。

Dependencies

              要使用mvel只需要一个mvel.jar即可

The MVEL Convenience Class

              为了使得使用简单和直接,mvel大部分的接口使用了静态方法,使得你在应用程序中可以直接使用

几乎所有的交互将围绕org.mvel2.MVEL类的使用。

 

Interpreted Mode

              正如本节所介绍,解释模式是一种快速、动态parser-interpreterMVEL,所谓的快是,指的是相比一些其他的EL实现.

调用解释器主要集中在MVEL类中的eval()方法。

              Integration Example: MVELTest.java

     import org.mvel.MVEL;
     public class MVELTest {
           public static void main(String[]args) {
                 String expression ="foobar > 99";
                 Map vars = new HashMap();
                 vars.put("foobar",new Integer(100));
                 // We know this expressionshould return a boolean.
                 Boolean result = (Boolean)MVEL.eval(expression, vars);
                 if (result.booleanValue()) {
                     System.out.println("Itworks!");
                }              
           }
     }

 

Compiled Mode

编译和执行一个表达式,需要做的不是简单地调用一个方法。它包括两种方法!

               Integration Example: MVELTest2.java

   

  import org.mvel.MVEL;
     public class MVELTest2 {
           public static void main(String[]args) {
                 String expression ="foobar > 99";
                 // Compile the expression.
                 Serializable compiled =MVEL.compileExpression(expression);
                 Map vars = new HashMap();
                 vars.put("foobar",new Integer(100));
                 // Now we execute it.
                 Boolean result = (Boolean)MVEL.executeExpression(compiled, vars);
                 if (result.booleanValue()) {
                     System.out.println("Itworks!");
                }              
           }
     } 

在MVEL2.0,您可以将编译器设置为强类型模式,这样类型转换会在脚本内部进行转换.这意味着必须告知编译器注入任何类型的变量。这也意味编译器可以在编译时告知返回类型。

Turning on StrongTyping

调用ParserContext的启动接口:setStrongTyping

// create new parser context
ParserContext ctx = newParserContext();
// turn on strong typing
ctx.setStrongTyping(true);
//compile an expression'str.toUpperCase()'
String expression ="str.toUpperCase()";
CompiledExpression ce =MVEL.compileExpression(expression, ctx);


运行上面的代码会报错

[Error: Failed to compile: 2 compilation error(s): 
 - (1,3) unqualified type in strict mode for: str
 - (1,17) unable to resolve method using strict-mode: java.lang.Object.toUpperCase(...)]

这是因为我们没有设置强制转换的类型,


// create new parser context
ParserContext ctx = new ParserContext();
// turn on strong typing
ctx.setStrongTyping(true); 
// declare the type of 'str'
ctx.addInput("str", String.class);
//compile an expression 'str.toUpperCase()'
String expression = "str.toUpperCase()";
CompiledExpression ce = MVEL.compileExpression(expression, ctx);


我们还可以通过CompiledExpression 对象的getEgressType()方法来确定返回的对象类型:

Class returnType = ce.getKnownEgressType(); // returns java.lang.String in this case.

MVEL还可以指定生产类型的类型参数,比如:


ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
// Specify the type of "foo" and it's type parameters. 
ctx.addInput("foo", HashMap.class, new Class[]{String.class, String.class});
String expression = "foo.get('bar').toUpperCase()";
Serializable ce = MVEL.compileExpression(expression, ctx);

在这种情况下,该表达式可以编译成功并执行,因为MVEL能够确定foo.get的返回类型根据输入的时候被指定的类型参数。

1.  Optimizers

优化器通常只使用于编译模式,而不考虑在eval解释模式下.

              由于MVEL是动态运行时的动态语言,所以需要通过反射的对象让脚本访问字段和方法。但这严重影响性能,MVEL配备优化,为了最大限度地减少或消除反射调用的开销。默认情况下,MVEL有两个默认优化:反射优化器,ASM字节码优化器。

反射优化器

              反射优化器在一些api中也被称为SAFE_REFLECTIVE优化器,表示他是绝对安全的,不会对类加载造成影响,保证兼容所有的语言结构.ASM优化器可能会在某些情况下,由于各种原因不能被编译成字节码,对于某些操作会依靠这个优化器。

优化器的配置可以通过MVELsOptimizerFactory进行配置:

              OptimizerFactory.setDefaultOptimizer("reflective");

The ASM (Bytecode) Optimizer

              ASM字节码优化器在MVEL是默认启用。它使用一个内联版本的ASM3.0字节码操作库产生编译反射访问器存根用于反射调用的地方。优化器是由默认使用API调用如下:

              OptimizerFactory.setDefaultOptimizer("ASM");

 

2.   Programmatic Imports for 2.0

              默认情况下,如java中,mvel自动将所有java.lang.* 预加载到了运行执行环境中去.同时,MVEL能够以编程方式导入单个类,整个包,甚至是静态方法.

              这样看来好像有点偏离了MEVL这个类,但是这个没有太大关系.

Importing Classes

              看下面代码:

   
 // where someExpression is a String or char[] of the expression to be compiled.
ParserContext context = new ParserContext();
context.addImport("Message", Message.class);
context.addImport("MessageFactory", MessageFactory.class);
Serializable compiled = MVEL.compileExpression(someExpression, context); // compile the expresion

上面的例子中我们为运行时添加了两个自定义的类型,他们都使用了原来的名称,但事实上你可以修改成任意合法的名称.比如:

context.addImport("Utils", ScriptUtilities.class);

Importing Packages

导入包:

ParserContext ctx = new ParserContext();
ctx.addPackageImport("java.util"); // imports the entire java.util.* package.
Serializable s = MVEL.compileExpression("map = new HashMap();", ctx);

Importing Static Methods

ParserContext ctx = new ParserContext();
try {
    ctx.addImport("time", System.class.getMethod("currentTimeMillis")); 
}
catch (NoSuchMethodException e) {
    // handle exception here.
}
Serializable s = MVEL.compileExpression("time();" ctx);   

3.   自定义变量解析器

4.   自定义属性处理程序

              略...见java doc文档

5.  类型转换

             略..

6.  行调试器接口

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值