суббота, 17 января 2009 г.

Жизненное: про Spring AOP


При поддержке: Все рестораны, кафе, бары Челябинска.

Решил, что помимо скучных "статейных" постов, иногда следует делиться с читателями и сведениями о своей программерской жизни.

На прошедшей неделе (понедельник начался в воскресение) наконец то удалось понять зачем нужен AOP (Aspect Oriented Programming) в реальных проектах и даже заюзать сею замечательную вещь через Spring.

Вообще, в нашем проекте (Spring + Hibernate) AOP уже давно используется для динамического создания транзакций. Выглядит это, как и советуют классики следующим образом:

- Определяем бин Hibernate Session Factory
- Определяем бин Transaction Manager (org.springframework.orm.hibernate3.HibernateTransactionManager)
- Определяем tx:advice, в котором описываем правила создания транзакций для тех или иных сигнатур методов
- С помощью AOP tx:advice при выполнении методов из каких классов он должен срабатывать. Тем самым эти методы станут "обернуты" в транзакции (согласно правилам, заданным при описании tx:advice).

Удобно? Очень удобно - теперь ненадо в коде методов руками создавать и коммитить транзакции, все делается динамически с помощью Spring и AOP.

Теперь предположим, нам надо после завершения выполнения метода уведомить какую-то внешнюю систему об этом радостном событии. Причем уведомить надо только если метод успешно завершился и - самое главное - после завершения транзакции, в которую этот метод "обернут". Если кому интересно зачем надо так извращаться - пишите в комменты, я отвечу.

Понятно, что писать код уведомления в последнюю строку метода нельзя - этот код будет выполнен когда транзакция еще не закоммичена, да и при коммите транзакции возможен Exception. Сам же метод дергается веб-сервисом, поэтому добавить код после метода - тоже невозможно.

Что мы делаем. Мы определяем аспект, который будет вызывать наш код уведомления после (aop:after-returning) успешного завершения нужного метода. Причем, транзакция, в которую обернут метод, к тому времени будет уже закрыта.

Подробнее про работу с AOP в Spring я еще напишу. Оставайтесь на связи.

Понравилось сообщение - подпишись на блог

6 комментариев:

Magicdream комментирует...

Уж очень АОП напоминает использование паттерна Слушатель(Listener). Эдакий "динамический слушатель" :)

Samolisov Pavel комментирует...

Да, в целом правильно подмечено. А "событием" является выполнение некоторого метода, например (в Spring есть и другие типы "событий" для AOP).

Анонимный комментирует...

Без AOP-таки можно обойтись... Гораздо удобнее использовать @Transactional перед нужными методами...

Samolisov Pavel комментирует...

@Transactional лишь обернет метод в транзакцию, что позволит не описывать в XML с помощью AOP управление TransactionManager'ом.

Надо кстати уточнить, возможно в рантайме все равно все работает через AOP.

Вторую же, описанную проблему @Transactional не решает.

black zorro комментирует...

>>Надо кстати уточнить, возможно в рантайме все равно все работает через AOP.

AOP - это всего лишь название технологии, т.е. идея (мол давайте вынесем часть общей функциональности вроде разметки транзаций, логгинг, права доступа и т.д. в специализированные объекты вызываемые до, после, вместо целевого метода). Техническая реализация и для основанного на аннотациях и на хмл-разметке пойдет через создание либо ProxyFactoryBean-а, либо через aspectj (вот первая хорошая ссылка по этой теме http://blogs.warwick.ac.uk/nickhowes/entry/spring_transactional_handling/).

skif комментирует...

а почему не подошли hibernate слушатели?
Если правильно все понял, то это как раз то что нужно.