挂钩Grails域对象save()

mbr*_*ort 7 grails groovy grails-plugin

我正在写一个grails插件,我需要挂钩到域save()方法,以便在保存后做一些逻辑.我需要在多个域类中执行此操作.我试图避免在插件用户没有使用带有GORM的hibernate的情况下的hibernate事件.

我尝试了很多东西,但下面是我认为应该有最好的工作机会.在所有情况下,grailsS​​ave都null.我怎样才能做到这一点?

def doWithDynamicMethods = { ctx ->
    application.domainClasses.each { dc ->
        def grailsSave = dc.metaClass.pickMethod('save', [Map] as Class[])

        domainClass.metaClass.save = { Map params ->
        grailsSave.invoke(delegate, [params] as Object[])
        println "Saved object, now do my thing"
        //...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的*Plugin.groovy类中有以下设置:

def dependsOn = [domainClass: '1.1 > *', hibernate: '1.1 > *']
def loadAfter = ['hibernate']
Run Code Online (Sandbox Code Playgroud)

mbr*_*ort 6

在插件/应用程序初始化期间,我无法成功获得对save()方法的引用; 我不知道为什么.相反,我决定在插入,更新和删除之后为hibernate事件创建一个监听器.Sean Hartsock关于审计日志插件的这篇文章是这样做的完美入门.

这是听众的要点:

class MyListener implements PostInsertEventListener, PostUpdateEventListener, PostDeleteEventListener, Initializable {

        public void onPostInsert(final PostInsertEvent event) {
            // logic after insert
            return
        }

        public void onPostUpdate(final PostUpdateEvent event) {
            // logic after update
            return
        }

        public void onPostDelete(final PostDeleteEvent event) {
            // logic after delete
            return
        }


        public void initialize(final Configuration config) {
            return
        }   
    }
Run Code Online (Sandbox Code Playgroud)

然后在*GrailsPlugin.groovy中:

def doWithApplicationContext = { applicationContext ->

    // add the event listeners for reindexing on change
    def listeners = applicationContext.sessionFactory.eventListeners
    def listener = new MyListener()

    ['postInsert', 'postUpdate', 'postDelete'].each({
       addEventTypeListener(listeners, listener, it)
    })

}


// copied from http://hartsock.blogspot.com/2008/04/inside-hibernate-events-and-audit.html
private addEventTypeListener(listeners, listener, type) {
    def typeProperty = "${type}EventListeners"
    def typeListeners = listeners."${typeProperty}"

    def expandedTypeListeners = new Object[typeListeners.length + 1]
    System.arraycopy(typeListeners, 0, expandedTypeListeners, 0, typeListeners.length)
    expandedTypeListeners[-1] = listener

    listeners."${typeProperty}" = expandedTypeListeners
}
Run Code Online (Sandbox Code Playgroud)

在一天结束时相当简单......