1

我的目标是执行带有绑定的 groovy 脚本,其中函数是预定义的,并且拦截器会注销执行时间和闭包评估的结果。我的示例代码是:

  binding.login = { ->
     binding.event.appname=='login'
  }  def gse = new GroovyScriptEngine("src/main/resources/rules")
  gse.run('DSL.groovy', binding)

在我的脚本中,我正在调用登录方法。一切正常,除了我不知道如何使用 MetaClass 拦截它。我的尝试喜欢

  Binding.metaClass.invokeMethod = { String name, args ->
                       println ("Call to $name intercepted... ")

不工作。后来我发现闭包是绑定的属性,而不是方法。在这种情况下有什么方法可以执行拦截以及如何执行?元类的正确对象是什么?值得注意的是,我的闭包在另一个嵌套闭包中执行。谢谢

4

1 回答 1

0

我不知道这是否是更好的解决方案,但我设法通过装饰绑定中的闭包来做你想做的事

binding = new Binding([
    login : { -> println "binding.login called" },
    echo : { String text -> println "test for $text" },
    foo : { a, b, c -> println "$a $b $c" }
])


binding.variables.each { key, value ->
    if (value instanceof Closure) 
    {
        binding.variables[key] = { Object[] args -> 
            long t0 = System.currentTimeMillis()

            value( *args )

            print "[$key method"
            print " args: $args "
            println " time: ${System.currentTimeMillis() - t0}]"
        }
    }
}


def gse = new GroovyScriptEngine(".")

gse.run('Bind.groovy', binding)

这是我的Bind.groovy

println " ** executing bind"
login()
echo("echo")
foo("test", 4, "echo")
println " ** bind script done"

MissingMethodException如果您没有将方法定义为绑定中的闭包,您也可以尝试/捕获 a 。

我还向您推荐 Laforge 在创建 DSL 时的幻灯片:

http://www.slideshare.net/glaforge/going-to-mars-with-groovy-domainspecific-languages

在这个幻灯片中,Laforge 展示了使用扩展脚本的类进行绑定;我认为这是一个很好的方法。更多面向对象。

更新

看看 mrhaki 将方法调用委托给基 Script 类的建议(也在 Guillaume 的幻灯片中):

http://mrhaki.blogspot.com.br/2011/11/groovy-goodness-create-our-own-script.html

我只是用它在 JFugue 上实现了一个 DSL,它马上就可以工作了。

于 2012-08-31T21:23:03.343 回答