........ MyDomainClass.metaClass.save = {-> -6ren">
gpt4 book ai didi

grails - "Overloading"标准 GORM CRUD 方法

转载 作者:行者123 更新时间:2023-12-02 07:54:34 26 4
gpt4 key购买 nike

想做以下事情:

BootStrap {  def init = {servletContext ->  ........  MyDomainClass.metaClass.save = {->      delegate.extraSave()     //////// how to call original save() here?  }}.........}

附言MyDomainClass#extraSave 定义为 public void extraSave(){.....}

最佳答案

首先,Bootstrap.groovy 可能不是进行这种元编程的最佳场所。这种方法的问题是当应用程序启动时将应用对类的更改,但是当应用程序重新加载时您可能会丢失这些更改。显然,这只是开发过程中的一个问题,如果您不介意每次进行更改时都重新启动服务器,则根本不是问题,但我敢打赌,这很快就会成为一个主要的烦恼。为了在重新加载应用程序时也应用更改,您应该将元编程移动到一个插件中,您可以在其中挂接到 onChange 应用程序生命周期事件。

所以步骤是:

  • 创建一个插件
  • 在插件描述符的 doWithDynamicMethodsonChange 闭包中进行元编程

这是一个完整的示例,我在其中“覆盖”了所有 Controller 类上的 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"
}
}

关于grails - "Overloading"标准 GORM CRUD 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1664096/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com