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

时间:2010-03-04 12:48:22

标签: 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 Audit Logging插件为例。但是,据我所知,它的作用是添加在适当的时间触发的新用户创建的方法。我想自动注入我的代码,以便用户不必担心任何事情,我不想破坏他原来的afterInsert()(或者它的任何方法)实现。

另外,我想对暴露的服务方法做同样的事情,以便为它们注入安全性。但是,根据我的阅读,由于BeanWrapper并且因为服务总是重新加载,所以它不起作用。有人能更好地向我解释这个吗?

提前致谢。

1 个答案:

答案 0 :(得分:3)

我认为您不需要重命名旧方法。你可以像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返回正确的方法。