我想在Grails中为我的域类实现Trigger
个对象的概念。 Grails允许我在我的域类中将beforeInsert()
之类的方法定义为handle insert, update and delete events,类似于SQL数据库具有数据库触发器概念的方式。但是为了区分问题,我想将所有触发逻辑移到域类之外。
理想情况下,我可以在我的域类中定义一个static
触发器类列表,然后在beforeInsert()
方法中迭代这些类。示例代码如下所示。
static beforeInsertTriggers = [AccountNameTrigger, AccountDumpTrigger]
def beforeInsert() {
for (Class<Trigger> triggerClass : beforeInsertTriggers) {
triggerClass.newInstance().using(this).execute()
}
}
我创建了一个sample Grails 2.5.4 project on GitHub来说明我正在尝试做什么。但问题是触发器字面上是独立的逻辑孤岛,没有自动装配服务的能力。如何更好地设置此Trigger
模式或类似的模式?所以我可以将服务和其他bean自动装入Trigger
实例?
我也在努力保持设计的简洁性和可读性。
对于它的价值,我的灵感部分也来自于Salesforce implements triggers作为独立代码的不同单位。
答案 0 :(得分:0)
将您的触发器注册为Singleton Beans,您可以注入其他服务/ bean。您可以通过resources.groovy创建自定义bean。
让我们以AccountDumpTrigger为例。让我们做一个简单的改变:
package grails.domain.trigger.demo.triggers
import grails.domain.trigger.demo.Account
import org.codehaus.groovy.grails.commons.GrailsApplication
/**
* Created by marty on 6/25/16.
*/
class AccountDumpTrigger extends AbstractTrigger<Account> {
GrailsApplication grailsApplication
@Override
void execute() {
println grailsApplication.isInitialised()
println resource.dump()
}
}
并在resources.groovy或插件的doWithSpring闭包中编码:
accountDumpTrigger(grails.domain.trigger.demo.triggers.AccountDumpTrigger) { bean ->
bean.factoryMethod = 'getInstance'
/*
either refer each bean individually or you can use:
bean.autowire = "byType"
OR
bean.autowire = "byName"
*/
grailsApplication = ref("grailsApplication")
}
在你的域名内:
static beforeInsertTriggers = [AccountDumpTrigger]
def beforeInsert() {
for (Class<Trigger> triggerClass : beforeInsertTriggers) {
triggerClass.instance.using(this).execute()
}
}
而不是在beforeInsert
中编写代码,您也可以通过注册AbstractPersistenceEventListener
的实现来执行相同的操作。这样您就不必重复代码了。你也可以把它移到父类。