我可以从Java动态地向Groovy基本脚本添加方法吗?

时间:2013-09-19 01:40:22

标签: groovy dsl

虽然这不是标准做法,但我很好奇是否可以将方法注入GroovyShell编译环境。

这个想法是有(像Java):

GroovyShell shell = new GroovyShell();
Script script = shell.parse("test()");
script.run();

我想动态添加可调用的方法,其中列出了test()

我已经尝试过使用Script metaClass,但是我没有看到从Java实际操作metaClass的方法。特别是,调用script.getMetaClass().getMethods().add(...)会抛出UnsupportedOperationException。

本质上,我想定义调用Java方法而不是基于Groovy方法的DSL调用点。我愿意在Groovy中写这个部分(我知道如何做到这一点),但我真的很好奇,如果这是一个可行的替代方法,或者如果不是,那么陷阱是什么。

简而言之:如何动态定义GroovyShell知道的方法?

2 个答案:

答案 0 :(得分:4)

这有两个非常简单的解决方案: a)典型的“脚本”方法 b)更加时髦的方法

a)只是在您的script-String前面添加一个定义方法的String。 b)正在引用绑定,例如在“测试”的名称下。该引用的值是Closure对象或具有“call(args)”方法的任何其他对象。 当执行脚本时,Groovy看到“test()”,它将首先尝试找到这样的方法,如果没有这样的方法,它会尝试将“test”解析为属性并在绑定中找到它。然后它将使用提供的参数(如果有的话)调用如此解析的引用(闭包)。

还有更高级的选项,如提供CompilerConfiguration,这些选项都列在“Groovy in Action,第2版”(无耻插件)的DSL章节中。

答案 1 :(得分:0)

我用 MethodClosure 搜索示例但没有运气。这对我有用:

Closure whoami = new Closure(this){
  @Override
  public Object call(Object... args) {
    //add custom logic here or read passed args
    return "javatar";
  }
};
Binding b = new Binding();
b.setVariable("whoami", whoami);

之后,我可以在我的 groovy 脚本中使用 whoami 作为方法

whoami()

如果是简单的方法,我更喜欢使用 Dierk 的选项 A:

<块引用>

只需在脚本字符串前面加上定义方法的字符串即可。

但是如果它很复杂,我使用Closure :D