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

Posted

技术标签:

【中文标题】Grails 文档中的自定义事件监听器示例【英文标题】:Custom event listener example in Grails documentation 【发布时间】:2013-07-28 15:26:21 【问题描述】:

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

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

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

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 版

【问题讨论】:

什么版本的 Grails? 根据EventTriggeringInterceptor 的文档,您至少需要使用 2.0。 已将版本添加到 Q... 【参考方案1】:

如果你这样做:

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

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

【讨论】:

【参考方案2】:

看起来应该可以,尽管我会做一些不同的事情。 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 

【讨论】:

谢谢。刚刚尝试过,eventTriggeringInterceptor 为空(无法在空对象上获取属性“数据存储”)-IntelliJ IDEA 也没有将eventTriggeringInterceptor 显示为已连接(旁边没有 bean 图标)。我刚刚注意到我的应用程序没有安装 Hibernate 插件(我们使用的是 MongoDB GORM),这可以解释一下吗? 添加了 Hibernate 插件并且它可以工作 - 但我不想要 hibernate 插件 - 可能看起来像一个遗留错误? Hibernate 插件也通过尝试进行休眠查找来破坏 GORM findAll 调用,尽管我的 DataSource.groovy 中没有休眠代码。我现在看到Table "PROJECT" not found; SQL statement。此外,以下部分(休眠事件)中的文档状态:“通常鼓励使用上述非休眠特定 API” - 因此此代码不应依赖于休眠恕我直言。编辑:或者它是一个Mongodb插件错误,预计将eventTriggeringInterceptor注入mainContext???【参考方案3】:

感谢this post,终于偶然发现了一个有效的Bootstrap.groovy,但我认为这不是最好的方法,而是一种解决方法。

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

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

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

【讨论】:

以上是关于Grails 文档中的自定义事件监听器示例的主要内容,如果未能解决你的问题,请参考以下文章

Grails 插件中的自定义 CSS 和 JS

从 grails 应用程序中的自定义 groovy 文件加载 spring bean

Grails 中的自定义验证器中的异常

自定义事件在 Vue.js 组件中的应用

Android 应用上的自定义事件监听器

Grails JSON 编组器中的自定义字符串格式