我的目标是使用绑定执行groovy脚本,其中函数是预定义的,拦截器注销执行时间和闭包评估的结果。我的示例代码是:
binding.login = { ->
binding.event.appname=='login'
} def gse = new GroovyScriptEngine("src/main/resources/rules")
gse.run('DSL.groovy', binding)
在我的脚本中,我正在调用login方法。一切正常,除了我不能弄清楚如何使用MetaClass拦截它。我的尝试喜欢
Binding.metaClass.invokeMethod = { String name, args ->
println ("Call to $name intercepted... ")
没用。后来我发现闭包是绑定的属性,而不是方法。 在这种情况下是否有任何方法可以执行拦截以及如何执行此操作?元类的正确对象是什么?值得注意的是,我的闭包在另一个嵌套闭包中执行。 感谢
答案 0 :(得分: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
。
我还建议您使用Laforge创建DSL的幻灯片:
http://www.slideshare.net/glaforge/going-to-mars-with-groovy-domainspecific-languages
在此幻灯片中,Laforge使用扩展脚本的类显示绑定;我认为这是一个很好的方法。更多OO。
<强>更新强>
看看mrhaki建议将方法调用委托给基类Script类(也在Guillaume的slideshare中):
http://mrhaki.blogspot.com.br/2011/11/groovy-goodness-create-our-own-script.html
我刚刚使用它在JFugue上实现了一个DSL,它立刻起作用了。