首先,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