Вот что я узнал, изучая мои варианты:
1) Встроенный код в контроллере / сервисе, который выполняет тегирование (не хочу делать это, так как он смешивает два разных бизнес-процесса.)
Не пробовал эту альтернативу
2) Использовать прослушиватели hibernate до обновления и после сбора обновления, чтобы получить необходимую информацию, создать исохраните новый UserTagEvent
Это оказалось очень трудным, неэффективным и проблематичным по нескольким причинам.
Например, вы работаете с коллекцией предметов, которые могут быть или не быть ленивыми инициализированы.Чтобы обнаружить изменения в коллекции, мне пришлось прослушать событие инициализации коллекции, получить клонированную коллекцию, сохранить ее в переменной поля, затем прослушать событие обновления коллекции, получить клонированную коллекцию и сравнить с ранее сохраненной коллекцией.
Кроме того, эти события запускались для ВСЕХ событий гибернации, а не только для объектов домена, в которых я был заинтересован. Так что это было "некуда" ...
3)Используйте AOP.
Изначально я был очень оптимистичен в отношении этого решения, и после нескольких попыток я вскоре понял, что это не так просто, как я думал вначале.В Интернете было очень мало руководств, описывающих Grails AND AOP, и они существовали довольно старые.
Работы было намного больше, чем я думал.У меня сложилось общее впечатление, что в grails, похоже, есть много ошибок, связанных с интеграцией AOP, и мне также не понравилось то, что мне пришлось добавлять определения bean-компонентов в resources.groovy для каждого созданного мной аспекта.Я пытался сделать так, чтобы аспекты загружались с помощью аннотаций (авто-прокси), но безуспешно.
Кроме того, я так и не получил pointcut для работы вне основного проекта.Поскольку мое решение для тегирования определено как плагин Grails, кажется, что AOP не может быть применен к классам плагина (даже если это плагин на месте).
Так что это оказалось "не ходи""aswell
Итак, барабанная дробь, пожалуйста.
Я закончил тем, что использовал шаблон наблюдателя для запуска события при добавлении или удалении нового тега.Это включало внесение изменений в мой плагин tagger, где я мог указывать слушателей через bean-компоненты (в которых реализован интерфейс TagEventListener) и чтобы плагин tagger запускал события для Spring-бинов при вызовах методов addTag и removeTag.
В целомЯ очень доволен этим решением, оно включает в себя еще один или два вызова методов, а не то, что было бы необходимо, если бы я только что добавил, как описано в варианте 1. Но таким образом у меня есть более чистый код, и я не смешиваю бизнес-процессы.Поэтому я думаю, что дополнительные 1 нс накладные расходы того стоят.