Grails文档中的自定义事件侦听器示例

时间:2013-07-28 23:07:20

标签: mongodb grails gorm bootstrapping

我正在尝试在Bootstrap.groovy中添加自定义GORM事件侦听器类,如Grails documentation中所述,但它不适用于我。以下是直接来自文档的代码:

def init = {
    application.mainContext.eventTriggeringInterceptor.datastores.each { k, datastore ->
        applicationContext.addApplicationListener new MyPersistenceListener(datastore)
    }
}

当我运行它时,编译器会抱怨application和applicationContext为null。我已经尝试将它们添加为类级别成员,但它们没有神奇的有线服务风格。我到目前为止最接近的是:

def grailsApplication
def init = { servletContext ->
    def applicationContext = servletContext.getAttribute(ApplicationAttributes.APPLICATION_CONTEXT)
    grailsApplication.mainContext.eventTriggeringInterceptor.datastores.each { k, datastore ->
        applicationContext.addApplicationListener new GormEventListener(datastore)
    }
}

但我仍然会收到错误:java.lang.NullPointerException: Cannot get property 'datastores' on null object

感谢阅读...

编辑:版本2.2.1

3 个答案:

答案 0 :(得分:8)

如果你这样做:

ctx.getBeansOfType(Datastore).values().each { Datastore d ->
   ctx.addApplicationListener new MyPersistenceListener(d)
}

这应该可以在不需要安装Hibernate插件的情况下工作

答案 1 :(得分:5)

看起来它应该有用,虽然我的做法有点不同。 BootStrap.groovy确实支持依赖注入,因此你可以注入grailsApplication bean,但你也可以直接注入eventTriggeringInterceptor

class BootStrap {

   def grailsApplication
   def eventTriggeringInterceptor

   def init = { servletContext ->
      def ctx = grailsApplication.mainContext
      eventTriggeringInterceptor.datastores.values().each { datastore ->
         ctx.addApplicationListener new MyPersistenceListener(datastore)
      }
   }
}

这里我仍然注入grailsApplication,但仅仅因为我需要访问ApplicationContext才能注册监听器。这是我的倾听者(比文档声称最简单的实现更简单;)

import org.grails.datastore.mapping.core.Datastore
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEvent
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener

class MyPersistenceListener extends AbstractPersistenceEventListener {

   MyPersistenceListener(Datastore datastore) {
      super(datastore)
   }

   protected void onPersistenceEvent(AbstractPersistenceEvent event) {
      println "Event $event.eventType $event.entityObject"
   }

   boolean supportsEventType(Class eventType) { true }
}

答案 2 :(得分:1)

最后偶然发现了Bootstrap.groovy,感谢this post,但我不认为这是最好的方法,而不是它的解决方法。

def init = { servletContext ->
    def applicationContext = servletContext.getAttribute(ApplicationAttributes.APPLICATION_CONTEXT)
    applicationContext.addApplicationListener new GormEventListener(applicationContext.mongoDatastore)
}

所以基本上我是直接对MongoDB数据存储区进行硬编码而不是像现有文档那样迭代可用的数据存储区。

为了节省您在第一个答案中阅读评论,我在问题中提供的改编版本(以及Burt的答案)仅在安装了 Hibernate插件时有效但在我的情况下我是使用 MongoDB插件所以不需要Hibernate插件(事实上它在其他方面打破了我的应用程序)。