是否可以使用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动态定义它们。
答案 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状态 - 这不是线程安全的