środa, 18 marca 2009

AbstractAdvisorAutoProxyCreator

Ostatnio dostałem zadanie dopisania paru rzeczy w projekcie wykorzystującym Spring Framework w wersji 1.2. Dodatkowo chciałem podbić wersję Springa do aktualnie wykorzystywanej w innych projektach, czyli do wersji 2.5.6. Parę razy już taką operację robiłem i zazwyczaj sprowadzało się to do wymiany jarów. Tym razem nie było inaczej i już po chwili aplikacja działała z nowym wersją Springa.
W projekcie należało dodać jedną prosty aspekt i chciałem wykorzystać do tego nową (dostępną już w wersji 2.0) składnie definiowania w xml konfiguracji Spring AOP, czyli korzystanie z przestrzeni nazw aop.
Po wprowadzeniu zmian i przetestowaniu, wyglądało jakby zadanie miało być skończone. Jednak zauważyłem dziwną rzecz: niektóre beany, które dotychczas nie były opakowywane przez żaden z aspektów zostały tym razem opakowane - zamiast POJO były to AOP proxy. Dotyczyło to tylko niektórych beanów, ale co ciekawsze zostały opakowane nie przez mój aspekt, ale przez inny istniejący zanim zacząłem wprowadzać zmiany.
Jak usunąłem wprowadzone przeze mnie zmiany wszystko zaczęło działać jak poprzednio i beany, które jeszcze przed chwilą widziałem jako Proxy teraz były zwykłymi POJO.
Wyglądało to jakby wprowadzenie nowego aspektu rozwaliło cała dotychczasową konfigurację Spring AOP.
Zacząłem przeglądać źródła Springa i po jakimś czasie znalazłem rozwiązanie. Problem wynikał z tego, że dotychczasowa konfiguracja Spring AOP opierała się na tworzeniu ProxyFactoryBean i podpinaniu do nich wszelkiego typu beanów będących Advisorami lub Interceptorami, a użycie nowej konfiguracji xml powoduję uaktywnienie się beana typu AspectJAwareAdvisorAutoProxyCreator, który to jest podklasą klasy AbstractAdvisorAutoProxyCreator. Klasa ta próbuje z każdego beana (tak nie do końca z każdego, ponieważ nie bierze pod uwagę pewnych klas beanów) stworzyć AOP proxy na podstawie zdefiniowanych w systemie advisorów. W wersji 1.2 aby otworzyć AOP proxy należało do beana typu ProxyFactoryBean podpiąć nazwe beana będący advisorem, to teraz sam Spring dla każdego beana wyszukuje liste advisorów, które do niego "można zastosować".
Jeśli lista ta nie będzie pusta, to tworzy dla danego beana AOP proxy i rejestruję w kontekście.

Zachowanie takie można zasymulować także w Springu 1.X poprzez dodanie do kontekstu beana typ DefaultAdvisorAutoProxyCreator.

Wielokrotnie słyszałem o tym aby nie mieszać różnych opcji konfigurowania tych samych rzeczy w Spring: choćby jednoczesnego definiowanie transakcji za pomocą annotacji i konfiguracji w xml. To samo dotyczy zresztą sposobu konfigurowania AOP, czego sam doświadczyłem.

Brak komentarzy:

Prześlij komentarz