当前位置: 首页 > 工具软件 > MVEL > 使用案例 >

mvel 调用java_Mvel使用指南

张啸
2023-12-01

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.  行调试器接口

 类似资料: