定义并重用MVEL功能

Ili*_*hko 1 java evaluation function embedding mvel

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

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

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动态定义它们.

Mik*_*ock 6

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

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

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

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

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

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

MVEL.executeExpression(s, myVarFactory);
Run Code Online (Sandbox Code Playgroud)

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

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