定义并重用MVEL功能

时间:2012-09-28 13:42:29

标签: java function embedding evaluation mvel

是否可以使用MVEL定义一些自定义预编译函数并在另一个编译表达式中使用一个? 如果我尝试以下内容:

MVEL.compileExpression("function hello() { System.out.println(\"Hello!\"); hello(); return x * y;");

第二次尝试执行时我得到Exception in thread "main" [Error: duplicate function: hello]

看起来我应该声明函数不在表达式本身,而是某种上下文。我和ParsedContext玩了一段时间,但总是得到Exception in thread "main" [Error: unable to access property (null parent): hello]

Internet上充满了涵盖不同MVEL语言使用主题的教程,但这些嵌入主题的文档记录很少。你能告诉我一些我做错的线索吗?

P.S。我不想从Java执行某些功能。我需要用MVEL动态定义它们。

1 个答案:

答案 0 :(得分:6)

这比一些常见的用例有点棘手,尽管有可能。

从根本上说,您需要创建一个定义函数的脚本,如下所示:

VariableResolverFactory functionFactory = new MapVariableResolverFactory();
MVEL.eval("def foo() { System.out.println("foo"); }; def bar() { System.out.println("bar") };", functionFactory);

然后,你所做的就是将这个工厂反向链接到你运行的任何表达式:

VariableResolverFactory myVarFactory = new MapVariableResolverFactory();
myVarFactory.setNextFactory(functionFactory);

Serializable s = MVEL.compileExpression("foo(); bar();");

MVEL.executeExpression(s, myVarFactory);

函数作为引用记录在变量表中,因此您可以使用常规变量工厂反向链接在MVEL中共享它们。

注意:您不应该重新分享'myVarFactory'。你想每次创建一个新的。您只想回收'functionFactory'并将其反链到每个运行的工厂,如上所示。否则,你最终会在执行之间共享本地var状态 - 这不是线程安全的