是否可以使用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语言用法主题的教程,但是此类嵌入主题的文献资料很少。您能给我一些提示我做错了什么吗?

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

最佳答案

尽管有可能,但是这比某些常见用例要复杂一些。

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

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

09-05 18:39