首先,Bootstrap.groovy可能不是做这种元编程的最佳地方。这种方法的问题在于,应用程序启动时会应用类的更改,但在重新加载应用程序时可能会丢失这些更改。显然,这只是开发过程中的一个问题,如果您不介意每次更改时重新启动服务器,都不是问题,但我敢打赌,这很快就会成为一大烦恼。为了在重新加载应用程序时应用更改,您应该将元编程移到插件中,在那里您可以挂接到应用程序生命周期事件。
因此,步骤是:
这里的doWithDynamicMethods
和onChange
倒闭的元编程是一个完整的例子我“覆盖”了所有控制器类上的chain()方法。同样对域类的save()方法做的代码只需要一些明显的替换,例如,使用application.domainClasses
代替application.controllerClasses
def doWithDynamicMethods = {ctx ->
application.controllerClasses.each {controller ->
replaceChain(controller)
}
}
def onChange = {event ->
if (application.isArtefactOfType(ControllerArtefactHandler.TYPE, event.source)) {
def clz = application.getControllerClass(event.source?.name)
replaceChain(clz)
}
}
private replaceChain(controllerClass) {
// Save a reference to the grails chain() method
def grailsChain = controllerClass.metaClass.pickMethod("chain", [Map] as Class[])
controllerClass.metaClass.chain = {Map params ->
println "My code to execute before chain goes here"
// Invoke the grails chain() method
grailsChain.invoke(delegate, [params] as Object[])
println "My code to execute after chain goes here"
}
}
昨天试过了。不起作用,说'origSave'是元类属性或东西,而不是闭包,就像那样。尝试不同的方式来调用它:'origSave()'和'origSave.call()' – Archer 2009-11-03 10:16:46
正确的代码在这里:http://stackoverflow.com/a/8388366/207791 – 2012-08-10 06:57:19