1

是否可以使用 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 语言使用主题的教程,但此类嵌入主题的文档记录非常差。你能给我一些线索我做错了什么吗?

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

4

1 回答 1

8

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

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

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 状态——这不是线程安全的

于 2012-09-29T00:58:39.067 回答