实现闭包委托的 methodMissing()

Implement methodMissing() for closure delegate

提问人:Andrew Sokolov 提问时间:5/11/2018 更新时间:5/11/2018 访问量:529

问:

我正在尝试使用 Java 和 Groovy 实现一个有点通用的 DSL。这个想法是有一个语法,类似于并拦截所有方法调用,我可以检查方法名称是否等于字段,并通过运行闭包进行设置。我使用 Java 编写我的数据类,它看起来像这样。data { name 'my name' }methodMissing

public class TestData {
    @Getter @Setter
    protected String name;

    public void call(Closure closure) {
        closure.setResolveStrategy(Closure.DELEGATE_FIRST);
        closure.setDelegate(this);
        closure.call();
    }

    public Object methodMissing(String name, Object args) {
        // here we extract the closure from arguments, etc
       return "methodMissing called with name '" + name + "' and args = " + argsList;
    }
}

运行 DSL 脚本的代码是这样的

    TestData testData = new TestData();
    Binding binding = new Binding();
    GroovyShell shell = new GroovyShell(binding);
    binding.setVariable("data", testData);
    Object result = shell.evaluate("data { name 'my test data' }");

问题是,返回一个:closure.call()MissingMethodException

groovy.lang.MissingMethodException: No signature of method: Script1.name() is applicable for argument types: (java.lang.String) values: [my test data]如何使它将方法调用重定向到其委托并查找其方法?methodMissing

Java Groovy 闭包

评论

1赞 adamcooney 5/11/2018
您可以使用返回脚本对象的 parse 方法,而不是使用 evaluate,然后在调用其 run 方法之前调用 setDelegate。
0赞 Andrew Sokolov 5/11/2018
谢谢。这很有帮助,但现在总是为我设置为脚本委托的实例调用。 不调用 的methodMissingTestDataclosure.setDelegate(value); closure.run()valuemethodMissing()
5赞 Andrew Sokolov 5/11/2018
我找到了解决方案:应该扩展,其中包含一个,反过来,它将所有丢失的方法调用重定向到正确的对象。TestDataGroovyObjectSupportMetaClassmethodMissing
1赞 aristotll 1/10/2023
@AndrewSokolov 为什么不编写自己的解决方案并接受它作为答案。

答: 暂无答案