Я пишу плагин чаш Грааля, и я должен сцепить в доменное сохранение () метод, чтобы сделать некоторую логику после сохранения. Я должен сделать это через несколько доменных классов. Я стараюсь избегать, в спящем режиме события в случаях, где сменный пользователь не использует, в спящем режиме с GORM.
Я попробовал многих, вещь, но ниже - то, что я думаю, должен был иметь лучшую возможность при работе. Во всех случаях grailsSave является пустым. Как я могу сделать это?
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"
//...
}
}
}
У меня есть следующий набор в моем *класс Plugin.groovy:
def dependsOn = [domainClass: '1.1 > *', hibernate: '1.1 > *']
def loadAfter = ['hibernate']
Я не смог успешно получить ссылку на методы save() при инициализации плагина/ приложения, не знаю почему. Вместо этого я решил создать слушатель для событий спящего режима после вставки, обновления и удаления. Эта запись Шона Хартсока относительно плагина Audit Logging была идеальным праймером для этого.
Вот суть слушателя:
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
}
}
Затем в *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
}
Довольно просто в конце концов...
.Посмотрите на плагин Falcone Util . Этот плагин позволяет подключаться к событиям Hibernate (см. Документацию внизу страницы). Не знаю, именно этого ли вы хотите, но вы можете получить несколько подсказок.
Пс! Я не думаю, что плагин работает с Grails 1.2.
Не лучше ли добавить это к классу обслуживания, которому принадлежит единица работы? Вот где обычная идиома Spring / Grails имеет такую логику. Вам вообще не нужно изменять сохранение.
В метаКласс добавлены три разных версии сохранения,
save(Map)
save(Boolean)
save()
Какую из них вы вызываете при тестировании? Вам нужно будет добавить код к каждой из них.
Еще одна вещь, которую нужно проверить, работает ли ваш плагин после плагина hibernate, который добавляет три метода в metaClass
cheers
Lee
.Это вопрос преждевременной оптимизации: старые версии Groovy серьезно наказали MetaClass, и поэтому GORM не добавляет всю свою магию до тех пор, пока не обнаружит в этом необходимости.
Самое простое решение - это иметь свою плагиновую зависимость от GORM Labs (я работаю с ней там). Альтернативным решением является запуск методаMissing вручную (который будет дублировать работу, которую я сделал). Смотрите документацию GORM Labs для получения подробной информации о том, как я это сделал.
. Дополнительные методы GORM лениво инициализируются при первом вызове любого из них.
Чтобы инициализировать их в doWithDynamicMethods
, просто вызовите один из статических методов в вашем доменном классе (-ах):
def doWithDynamicMethods = { ctx ->
application.domainClasses.each { dc ->
// call any static method to initialize dynamic gorm methods
dc.clazz.count()
def grailsSave = dc.metaClass.pickMethod('save', [Map] as Class[])
//...
}
}
Теперь ваш метод save () будет доступен. Поскольку это вызывается при запуске, единичный подсчет не должен быть большой проблемой.