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 文档中的自定义事件监听器示例的主要内容,如果未能解决你的问题,请参考以下文章