我想显示在某些插件上由doWithDynamicMethod调用的persistentProperties值

使用以下代码,我设法拦截了域类的保存和更新方法,并在他们尝试保存对象时看到了它们的输出。

但是我无法打印persistentProperties的内容(也许是因为我对groovy和grails不满意,因此我对groovy反射的语法不熟悉。

有人可以帮忙吗?

以下是我的代码:

def doWithDynamicMethods = { ctx ->
   // TODO Implement registering dynamic methods to classes (optional)

   application.domainClasses.each { gc ->

      def domainClass = gc.clazz
      domainClass.metaClass.invokeMethod = { name, args ->

         if (name == 'save' || name == 'update')
            delegate.log.info " ${delegate.class.name}.$name() args: $args"

         new DefaultGrailsDomainClass(delegate.class).persistentProperties.each{ property ->

            delegate.log.info "printing properties => "+ property.name+ "  "
         }//end persistentProperties.each

      }//endmetaClass.invokeMethod
   } //end domainClasses.each
}//end doWithDynamicMethod

最佳答案

如果我了解您要执行的操作,则您的代码当前正在列出与域类本身相关联的persistentProperties。要实际获取属性的值,您需要传递属性名称。

例如,如果您具有以下域类:

class Book {
    String title
    String lang
}

如果您要像这样保存新的Book:
def b = new Book(title: 'Hemingway', lang: 'en-us').save()

您的代码应打印出如下内容:
printing properties => title
printing properties => lang

如果您希望它打印如下内容:
printing properties => Hemingway
printing properties => en-us

然后,您必须从obj本身访问该属性:
def doWithDynamicMethods = { ctx ->
    application.domainClasses.each { gc ->
        def domainClass = gc.clazz
        domainClass.metaClass.invokeMethod = { name, args ->
            def domainObj = delegate

            if (name == 'save' || name == 'update') {
                new DefaultGrailsDomainClass(domainObj.class).persistentProperties.toList().each { property ->
                    domainObj.log.info "printing properties => " + domainObj[property.name]
                }
            }

            def called = domainClass.metaClass.getMetaMethod(name, args)
            called?.invoke(domainObj, args)
        }
    }
}

还有其他一些陷阱。变量delegate对每个闭包来说都是特殊的。如果您确实在运行它,则可能根本看不到“打印属性...”日志消息,因为在delegate.log.info闭包内部对each的调用中,delegate指的是闭包封闭类。另外,如果要从domainObj中读取属性,则应确保它位于名称if子句中,否则将再次调用invokeMethod

最后,您应该获取最初被调用的metaMethod并调用它,否则它实际上将不会保存/更新。

10-07 19:42
查看更多