grails - 在 Grails/Groovy 中拦截或重命名方法调用

标签 grails groovy interceptor

我正在尝试拦截 Grails 应用程序中的方法调用(域类的 afterInsert())。在我的插件的 doWithDynamicMethods 关闭中,我有:

for (dc in application.domainClasses) {
    // What I'm basically doing is renaming method A to B
    // and creating a new method A with its own business logic
    // and a call to B() at the end

    def domainClass = dc.getClazz()
    def oldAfterInsert = domainClass.metaClass.afterInsert
    domainClass.metaClass."afterInsert_old" = oldAfterInsert

    dc.metaClass.afterInsert = {
        // New afterInsert() logic here

        // Call the old after insert
        delegate.afterInsert_old()
    }

}

但随后我收到此错误:

No signature of method: static com.example.afterInsert_old() is applicable for argument types: () values: []

我也尝试用 dc.metaClass."afterInsert_old".invoke(delegate, new Object[0]) 调用它,但后来我得到:

Caused by: groovy.lang.MissingMethodException: No signature of method: groovy.lang.ExpandoMetaClass$ExpandoMetaProperty.invoke() is applicable for argument types: (com.example.DomainName, [Ljava.lang.Object;) values: [com.example.DomainName : 115, []]

我做错了什么?如何调用不带参数的方法?

我了解 AOP,也见过 Grails 审计日志插件作为示例。然而,据我所知,它的作用是添加新的用户创建的方法,并在正确的时间触发。我想自动注入(inject)我的代码,这样用户就不必担心任何事情,并且我不想破坏他原来的 afterInsert() (或任何方法)实现。

此外,我想对公开的服务方法执行相同的操作,以便为它们注入(inject)安全性。然而,据我所知,由于 BeanWrapper 以及服务总是重新加载,它无法工作。有人可以向我更好地解释一下吗?

提前致谢。

最佳答案

我认为您不需要重命名旧方法。你可以像 this example 那样做:

for (dc in application.domainClasses) {
    // What I'm basically doing is renaming method A to B
    // and creating a new method A with its own business logic
    // and a call to B() at the end
    def domainClass = dc.getClazz()
    def savedAfterInsert = domainClass.metaClass.getMetaMethod('afterInsert', [] as Class[])
    domainClass.metaClass.afterInsert = {
        // New afterInsert() logic here

        // Call the old after insert
        savedAfterInsert.invoke(delegate)
    }

}

只需确保 getMetaMethod 返回正确的方法即可。

关于grails - 在 Grails/Groovy 中拦截或重命名方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2379324/

相关文章:

linux - 我可以对 bash 中输入的命令使用react吗?

java - JCIFS 访问被拒绝

grails - Grails quartz 作业永不执行

java - grails 中的 log4j : how to log into file?

linux - 当 while/if/etc 出现错误时如何使 bash 脚本失败?

groovy - 如何在 Eclipse RCP 项目中使用 groovy?

groovy - 从范围列表中删除重叠范围 Groovy

grails - grails cxf访问soap header

java - 如果围绕操作类创建代理建议,Spring Web 应用程序上下文不会返回 Struts2 操作方法

java - 覆盖或禁用 CDI 与 Bean 验证的集成