You are on page 1of 67

Spring Framework dla praktykw

Piotr Maj 27 marca 2006

ii

Spis treci

1. Wprowadzenie 1.1. Wane informacje dla czytelnikw . . . . . . . . . . . . . . . . 1.2. O autorze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3. Dla kogo przeznaczona jest ta ksika? . . . . . . . . . . . . . 1.4. Cel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5. Zakres materiau . . . . . . . . . . . . . . . . . . . . . . . . . 1.5.1. Omawiane zagadnienia . . . . . . . . . . . . . . . . . . 1.5.2. O czym nie jest ta ksika? . . . . . . . . . . . . . . . 1.6. Rekomendowane lektury . . . . . . . . . . . . . . . . . . . . . 1.6.1. Ksiki . . . . . . . . . . . . . . . . . . . . . . . . . . 1.6.2. Strony WWW . . . . . . . . . . . . . . . . . . . . . . 1.7. Narzdzia przydatne podczas lektury . . . . . . . . . . . . . . 1.8. Przyjte konwencje . . . . . . . . . . . . . . . . . . . . . . . . 1.9. Podzikowania . . . . . . . . . . . . . . . . . . . . . . . . . . 2. Wprowadzenie do Spring Framework 2.1. Kolejny framework?! . . . . . . . . . . . . . . . . . . . . . . . 2.1.1. W mnogoci sia? . . . . . . . . . . . . . . . . . . . . . 2.1.2. Wady tradycyjnych platform . . . . . . . . . . . . . . iii

1 1 1 2 3 3 3 4 4 4 5 5 5 5 7 8 8 8

Spis treci 2.1.3. Rozsdny kompromis Spring Framework . . . . . . . 2.2. Dlaczego powsta Spring Framework? . . . . . . . . . . . . .

iv 10 11 12 13 15 16 17 23 25 27 27 30 30 31 34 35 41 42 43 45 45 47 49 51 54

2.3. Architektura . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4. Zalety . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3. Bean i kontener IoC 3.1. Bean i fabryka beanw . . . . . . . . . . . . . . . . . . . . . . 3.1.1. Deniowanie prostych beanw . . . . . . . . . . . . . . 3.1.2. Cykl ycia . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.3. Niestandardowe edytory waciwoci . . . . . . . . . . 3.1.4. Bean bez domylnego konstruktora . . . . . . . . . . . 3.1.5. Tworzenie beanw przy pomocy fabryki . . . . . . . . 3.1.6. Relacje dziedziczenia . . . . . . . . . . . . . . . . . . . 3.2. Kontener IoC . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1. Deniowanie zalenoci midzy beanami . . . . . . . . 3.2.2. Sprawdzanie poprawnoci konguracji beanw . . . .

3.2.3. Automatyczne dopasowywanie zalenoci . . . . . . . 4. Programowanie aspektowe w Spring Framework 4.1. Wstp do aspektw . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1. Obiekty Proxy . . . . . . . . . . . . . . . . . . . . . . 4.2. Aspekty pod lup . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.1. Koncepcja AOP . . . . . . . . . . . . . . . . . . . . . 4.2.2. Sposoby implementacji AOP . . . . . . . . . . . . . . 4.2.3. Zastosowania AOP . . . . . . . . . . . . . . . . . . . . 4.2.4. Frameworki AOP . . . . . . . . . . . . . . . . . . . . . 4.3. AOP w Spring Framework . . . . . . . . . . . . . . . . . . . .

Spis treci

4.3.1. org.springframework.aop.framework.ProxyFactoryBean 54 Podsumowanie 55

Spis treci

vi

ROZDZIA 1

Wprowadzenie
wprowadzenie

1.1. Wane informacje dla czytelnikw


Niniejsza ksika jest dystrybuowana w takiej postaci w jakiej jest. Autor nie ponosi adnej odpowiedzialnoci za ewentualne szkody powstae w wyniku wykorzystania zawartych w tej ksice informacji. Wszelkie prawa autorskie zastrzeone. Reprodukcja i redystrybucja w formie oryginalnej lub zmienionej bez pisemnej zgody autora zabroniona. Kontakt z autorem: pm@jcake.com.

1.2. O autorze
Piotr Maj absolwent Akademii Ekonomicznej we Wrocawiu (obrona w 2002 r.), programista z zamiowania, w Javie programuje od 4 lat. Wsptwrca i redaktor portalu dla mionikw Javy http://jdn.pl/. 1

1.3. Dla kogo przeznaczona jest ta ksika?

Waciciel rmy jcake software http://jcake.com/ zajmujcej si tworzeniem aplikacji internetowych, programw w Javie (server side oraz desktop Eclipse RCP), a take szkoleniami dot. technologii Eclipse RCP. Wygoszone prelekcje: 1. Przenone aplikacje w Javie Eclipse RCP 22.09.2005, wykad na Politechnice witokrzyskiej w ramach spotka Kieleckiej Grupy Uytkownikw Linuksa. 2. Przenone aplikacje w Javie Eclipse RCP 26.10.2005, wykad na konferencji Java Techconf organizowanej przez Naukowe Koo Informatyki przy AE w Krakowie oraz serwis jdn.pl. 3. Przenone aplikacje w Javie Eclipse RCP 24.02.2006, wykad dla deweloperw w rmie Rector http://www.rector.com.pl/.

1.3. Dla kogo przeznaczona jest ta ksika?


Niniejsza ksika przeznaczona jest dla wszystkich deweloperw, ktrzy chcieliby tworzy nowoczesne aplikacje klasy enterprise w prosty i efektywny sposb. Poka, w jaki sposb mona ten cel osign wykorzystujc nowoczesn platform programow Spring Framework. Osoby zaczynajce dopiero sw przygod z aplikacjami internetowymi pisanymi w jzyku Java, znajd tu wyczerpujcy opis projektu Spring Framework wraz z przykadami jego praktycznego zastosowania. Ci, ktrzy wstp do programowania po stronie serwera maj ju za sob, ale nie mieli dotychczas okazji zapozna si z projektem Spring Framework ksika ta umoliwi poznanie zalet tej pod wieloma wzgldami rewolucyjnej platformy. Wszyscy uytkownicy Spring Framework znajd tu take szereg praktycznych porad i gotowych rozwiza problemw, na ktre natkn si i z ktrymi musia zmierzy si autor w trakcie wielomiesicznej pracy z tym projektem.

1.4. Cel

1.4. Cel
Gwnym celem i motywacj do napisania tej ksiki jest ch przedstawienia alternatywnego sposobu tworzenia aplikacji internetowych opartego na nieco innych zaoeniach ni najmodniejsze obecnie podejcie wykorzystujce komponenty EJB i serwery aplikacji zgodne ze standardem J2EE. To ostatnie czsto niepotrzebnie wprowadza duy stopie skomplikowania do programw, sprawia, e s one mao czytelne, charakteryzuje je niska wydajno, a co waniejsze, czsto s modelowym przykadem przerostu formy nad treci.

1.5. Zakres materiau


1.5.1. Omawiane zagadnienia
Zakres tematyczny ksiki obejmuje wszystko to, co ma do zaoferowania platforma Spring Framework, a wic w szczeglnoci:

konguracj kontekstu i kontener IoC, wsparcie dla programowania aspektowego w Spring Framework, zarzdzanie transakcjami, omwienie warstwy dostpu do baz danych i utrwalania obiektw, zdalne wywoywanie metod w Spring Framework, prezentacja implementacji wzorca MVC.

Wszystkie zagadnienia zostay omwione w takim stopniu, aby po przeczytaniu tej ksiki czytelnik mg w peni wykorzysta potencja Spring Framework we wasnym projekcie.

1.6. Rekomendowane lektury

1.5.2. O czym nie jest ta ksika?


Wiemy ju, jakie zagadnienia zostan w niniejszej ksice poruszone. Teraz sw kilka na temat tego, czym ona nie jest. Przede wszystkim nie jest to wprowadzenie do wiata serwletw, JSP i serwerw aplikacji. Zagadnienie to samo w sobie jest na tyle ciekawe i zoone, e mogoby posuy za temat do osobnej ksiki. W tej publikacji zakadam, e czytelnikowi znane s wyej wymienione zagadnienia w stopniu przynajmniej podstawowym, umoliwiajcym samodzielne skongurowanie i uruchomienie serwera aplikacji oraz tworzenie deskryptora aplikacji web.xml. W ksice wiele razy pojawi si odwoania do wzorcw projektowych, takich jak MVC czy IoC. Niemniej jednak ksika ta nie omawia wzorcw projektowych, a jedynie ich konkretne implementacje. Czytelnik powinien zapozna si z teori we wasnym zakresie.

1.6. Rekomendowane lektury


1.6.1. Ksiki
Czytelnikw, ktrzy s mniej biegli w programowaniu, zachcam przed przeczytaniem tej lektury do zapoznania si z publikacjami dotyczcymi bezporednio samego jzyka Java. Do penego zrozumienia niniejszej ksiki wane jest, aby czytelnik wiedzia w szczeglnoci co to s i jak dziaaj mechanizmy odzwierciedle (ang. reection) oraz dynamicznych porednikw (ang. dynamic proxy). Godn polecenia lektur jest ksika Thinking in Java autorstwa Brucea Eckela [?], dostpna nieodpatnie w formacie e-book lub odpatnie w wersji drukowanej (rwnie w polskiej wersji jzykowej). Z zagadnieniami zwizanymi z serwletami i JSP mona si zapozna dziki lekturze Java Servlet i Java Server Pages Martyiego Halla.

1.7. Narzdzia przydatne podczas lektury

1.6.2. Strony WWW


http://www.martinfowler.com/ - Strona Martina Fowlera - guru wzorcw projektowych

1.7. Narzdzia przydatne podczas lektury


Podczas pisania tej ksizki autor korzysta wycznie z oprogramowania dystrybuowanego na zasadach open source. W celu uruchomienia doczonych przykadw naley zaopatrze si w nastpujce narzdzia:

Spring Framework (http://www.springframework.org/), Ant (http://ant.apache.org/), Tomcat (http://jakarta.apache.org/tomcat/), hsqldb (http://hsqldb.sourceforge.net/), Hibernate (http://www.hibernate.org/).

Dodakowo potrzeba oczywicie rodowiska J2SDK 5.0, ktre mona pobra ze strony rmy Sun (http://java.sun.com/j2se/1.5.0/download.jsp), oraz dowolny edytor kodu lub rodowisko IDE (np. Eclipse).

1.8. Przyjte konwencje


przyjte konwencje

1.9. Podzikowania
Dzikuj Piotrowi Kobdzie za, jak zawsze, cenne uwagi jakimi si ze mn podzieli po przeczytaniu szkicu rozdziau powiconego teorii AOP.

1.9. Podzikowania

Dzikuj Michaowi Ciechelskiemu i Tomaszowi Bartkowiczowi za wnikliwe przeczytanie niniejeszego opracowania i znalezienie mnstwa literwek i innych potkni jzykowych.

ROZDZIA 2

Wprowadzenie do Spring Framework


Tworzenie zoonych aplikacji nie jest w dzisiejszych czasach rzecz prost. Zreszt nigdy tak nie byo, ale wszechpanujca obecnie triada szybciej, lepiej, taniej znacznie to zadanie komplikuje. Z drugiej strony na spraw patrzc, w typowych systemach zawsze znajdzie si taka cz kodu, ktra jest co prawda niezbdna do prawidowego funkcjonowania aplikacji, ale nie jest cile zwizana z jej logik biznesow, a w dodatku jest powtarzalna i z czasem po prostu nudna do pisania. Majc na wzgldzie powysze dwie uwagi moemy szybko doj do wniosku, e szanse napisania w rozsdnym czasie dobrej i taniej aplikacji (w sensie iloci powiconych osobogodzin) wzrosn, jeeli skoncentrujemy si tylko i wycznie na faktycznym rozwizywaniu problemw jej logiki biznesowej, ograniczajc do niezbdnego minimum wszystko to, co teje logiki bezporednio nie dotyczy. Logika biznesowa potrzebuje jednak rodowiska, w ktrym bdzie moga swobodnie funkcjonowa, a skoro my, gonieni terminami i ograniczeni budetem, nie mamy czasu na samodzielne jego stworzenie, powinnimy poszuka gotowego rozwizania dostarczajcego odpowiedniej infrastruktury. W ten sposb dotarlimy do pojcia framework , czyli aplikacji szkieletowej, ktra sama w sobie niewiele potra, ale za to dostarcza szeregu gotowych narzdzi i wzorcw, ktre umoliwiaj deweloperom skoncentrowanie si dokadnie na tym, co w danym projekcie jest najwaniejsze. 7

2.1. Kolejny framework?!

2.1. Kolejny framework?!


Od przybytku gowa nie boli gosi stare polskie przysowie, ktrego autorzy nie mogli zapewne przypuszcza, e powstanie co takiego jak aplikacja typu framework. . .

2.1.1. W mnogoci sia?


Na przestrzeni ostatnich kilku lat powstao co najmniej kilkanacie rnych platform do tworzenia aplikacji internetowych, z ktrych kada realizuje nieco odmienne podejcie do tego zagadnienia i oferuje inny zakres funkcjonalny. Cz z nich to po prosta implementacja wzorca projektowego MVC (ang. Model-View-Controller ), ktrej najbardziej znanym przykadem, uwaanym de facto za standard, jest projekt Struts. Przeciwwag dla nich stanowi platformy prawie gotowe do uycia i wyposaone w arsena narzdzi pokrywajcych swoim zakresem funkcjonalnym cay standard J2EE (np. Expresso). Gdzie pomidzy plasuje si najwicej projektw, ktre implementuj wzorzec MVC i jeden lub kilka wybranych aspektw aplikacji internetowych, takich jak zarzdzanie dostpem do baz danych czy kontener IoC, etc. Zorientowanie si w tym wszystkim, jeeli nawet nie powoduje to blu gowy to lekkie zawroty napewno. Ktra platforma jest najlepsza i co skonio autorw Spring Framework do stworzenia kolejnej?

2.1.2. Wady tradycyjnych platform


Zanim odpowiemy na powysze pytanie sprbujmy zastanowi si jakie wady maj dotychczasowe platformy? Oczywicie inne wady mona dostrzec w prostych implementacjach wzorca MVC, a inne w kombajnach ze wsparciem dla standardu J2EE. Gwnym argumentem przeciwko tym pierwszym jest to, e prosty framework jest zbyt prosty, aby mg znaczco wpyn na wzrost wydajnoci procesu tworzenia aplikacji, poniewa:

2.1. Kolejny framework?!

wymaga powicenia dodatkowego czasu na stworzenie nowych bd poznanie i integracj gotowych rozwiza wykonujcych brakujce platformie funkcje, nie oferuje wsparcia dla transparentnego spenienia zalenoci midzykomponentowych.

Framework, ktry oferuje jedynie podstawowe narzdzia w zakresie obsugi da HTTP i kontroli przepywu danych z modelu do widoku to zdecydowanie za mao. Kada aplikacja korzysta z pewnych zasobw zewntrznych (np. baz danych, serwera SMTP). Jeeli framework nie oferuje gotowych mechanizmw usprawniajcych dostp do zasobw bdziemy musieli straci czas albo na implementacj wasnych pomysw, albo na integracj naszego projektu z innymi, komplementarnymi. Aplikacje skadaj si przewanie z wielu komponentw, z ktrych kady odpowiedzialny jest za pewien wybrany aspekt systemu. Jest wiele przypadkw, w ktrych funkcjonalno komponentw w jakim stopniu si pokrywa. Za prosty przykad niech nam posuy komponent odpowiedzialny za tworzenie konta uytkownia, ktry moe chcie wysa e-mail z potwiedzeniem faktu rejestracji. Aby nie tworzy dwukrotnie kodu wysyajcego e-mail mona utworzy komponent, ktrego domen bdzie wysyanie listw elektronicznych i przekaza referencj tego komponentu do kadego innego, ktry takiej funkcjonalnoci potrzebuje. Istnieje wiele sposobw na zrealizowanie tego zadania niestety proste platformy MVC nie wspieraj adnego z nich, kolejny raz odcigajc programist od rzeczywistej pracy nad systemem. . . Zaawansowane platformy z kolei pozbawione s przewanie wyej wymienionych wad. Niestety, to co ma stanowi o ich sile, a wic kompleksowe podejcie do zagadnie infrastruktury czsto staje si ich najwikszym balastem. Narzdzia te s przewanie: skomplikowane, zmuszajce do stosowania pewnych, przyjtych przez ich twrcw, schematw,

2.1. Kolejny framework?!

10

czsto nie przystajce do specycznych wymaga naszego projektu. Stopie zoonoci platformy nie pozostaje bez wpywu na wydajno zespou projektowego, poniewa potrzeba przeznaczy sporo czasu na jej dokadne poznanie i zrozumienie. Jest to konieczne, jeeli chcemy w peni wykorzysta moliwoci oferowane przez framework. Decydujc si na taki framework tracimy kontrol nad sposobem implementacji pewnych aspektw, przez co nie tylko platforma, ale i tworzony w oparciu o ni system moe by bardziej skomplikowany ni by tego wymagaa sytuacja. Kompleksowe rozwizania przewanie narzucaj pewne schematy postpowania, ktre niekoniecznie musz pokrywa si z naszym rozumieniem dobrych praktyk programistycznych. Niestety, korzystajc z gotowca niewiele moemy na to poradzi musimy zda si na efekt przemyle twrcw platformy, rezygnujc z wasnych. To nie musi by samo w sobie wad, jednak praktyka pokazuje, e wikszo programistw i tak tworzy wasne alternatywne rozwizania eliminujce niedostatki platformy, bd lekko zmieniajc jej semantyk. Celem wielu autorw rozbudowanych platform do tworzenia aplikacji jest stworzenie systemu kompleksowego, ktry bdzie mona przystosowa do dowolnego typu aplikacji, wreszcie ktry bdzie w stanie zadowoli wikszo uytkownikw. Prowadzi to do pewnych uproszcze i koncentrowania si na wikszoci typowych przypadkw. Niestety, nie zawsze jestemy w tej komfortowej sytuacji, e piszemy typowy system, czsto specyczne wymagania klienta wykraczaj daleko poza te ramy, co wymusza albo przerabianie gotowego rozwizania albo implementacj wasnego od podstaw.

2.1.3. Rozsdny kompromis Spring Framework


Analizujc powysze wady nasuwa si pytanie, jak si ich skutecznie pozby nie tracc jednoczenie niczego z elastycznoci i funkcjonalnoci kompleksowych platform? Ideaem byby framework, ktry nie narzuca adnych gotowych rozwiza, ale jednoczenie byby wyposaony we wszelkie mechanizmy uatwiajce

2.2. Dlaczego powsta Spring Framework?

11

tworzenie aplikacji, z ktrych to mechanizmw moglibymy skorzysta zalenie od potrzeb. Spring Framework stara si realizowa to wanie podejcie dostarczy budulca bez wskazywania jedynie susznej drogi jego zagospodarowania. Cho, jak si pniej przekonamy, Spring Framework doskonale to zadanie realizuje dystansujc pod wieloma wzgldami inne platformy, wcale nie to byo gwnym celem i motywacj autorw podczas jego tworzenia.

2.2. Dlaczego powsta Spring Framework?


Spring Framework autorstwa Roda Johnsona i Juergena Hoellera jest projektem rozwijanym nieprzerwanie od pocztku 2003 roku. Sami autorzy wymieniaj szereg powodw, ktre skoniy ich do jego napisania [?]:

1. Stworzenie zintegrowanej platformy oferujcej solidn infrastruktur dla podstawowych aspektw kadej aplikacji. Istnieje wiele ciekawych i godnych uwagi projektw, ktre obejmuj swym zakresem funkcjonalnym pojedynczy aspekt zoonej aplikacji (np. PicoContainer jako kontener IoC, Hibernate jako narzdzie do mapowania O/R). Niestety ich integracja jest czasochonna i odciga programistw od zajmowania si rzeczywistymi problemami logiki biznesowej aplikacji. Spring Framework oferuje gotowe do uycia komponenty stanowice dobrze przetestowan, stabiln platform do tworzenia aplikacji. 2. Minimalizacja stopnia zoonoci platformy. Wikszo typowych, prostych problemw aplikacji internetowych powinno da si rozwiza przy uyciu prostych rodkw. Zdecydowanie naley unika zalenoci od skomplikowanych mechanizmw, jak np. JTA, jeeli tylko nie ma ku temu wyranych powodw. 3. Nieinwazyjno. Nasza aplikacja nie powinna, a jeeli ju to tylko w minimalnym stopniu zalee od infrastruktury platformy. Duy stopie

2.3. Architektura

12

niezalenoci mona osign przez zastosowanie kontenera IoC oraz programowania aspektowego. 4. Prostota testowania. Pisanie automatycznych testw kodu aplikacji powinno by proste, a poszczeglne komponenty systemu atwo zastpowalne na czas testw obiektami zastpczymi (ang. mock objects). 5. atwo rozbudowy. Platforma powinna promowa programowanie zorientowane na interfejsy, a nie na konkretne klasy, co umoliwia proste dostosowywanie jej do wasnych potrzeb. Co wane, Spring Framework nie jest projektem laboratoryjnym, napisanym w oderwaniu od rzeczywistoci. Powstawa w procesie ewolucyjnym, a jego przydatno zostaa pozytywnie zwerykowana przez autorw w kilku duych komercyjnych projektach, nad ktrymi mieli okazj pracowa.

2.3. Architektura
Spring Framework charakteryzuje si wielowarstow budow. Poszczeglne warstwy s waciwie osobnymi, niezwizanymi ze sob podprojektami. Istnieje jednake jeden element, ktry umoliwia szybkie i proste zintegrowanie poszczeglnych czci, a jest nim kontener IoC. Taki podzia czyni ze Spring Framework bardzo elastyczn konstrukcj, ktr mona dowolnie kongurowa w zalenoci od potrzeb. Warty podkrelenia jest rwnie fakt, e architektura ta nie ogranicza w aden sposb Spring Framework do jednego konkretnego zastosowania. Wrcz przeciwnie framework ten doskonale si sprawdza zarwno w aplikacjach internetowych, jak i okienkowych programach uytkowych. Na poszczeglne warstwy Spring Framework skadaj si nastpujce elementy [?]: kontener IoC (ang. Inversion of Control ), zarzdzanie kontekstem aplikacji,

2.4. Zalety wsparcie dla AOP, zarzdzanie transakcjami, abstrakcja DAO, wsparcie dla JDBC, integracja z narzdziami do mapowania O/R, implementacja wzorca MVC, wsparcie dla web-services.

13

W kolejnych rozdziaach szczegowo omwione zostan poszczeglne warstwy Spring Framework.

2.4. Zalety
Czym takim wyrnia si Spring Framework? Co powinno nas przekona akurat do tego jednego, spord kilkunastu dostpnych darmowych frameworkw? Moja osobista lista zalet wyglda nastpujco: Spring Framework to rozwizanie kompleksowe framework ten oferuje wsparcie dla wszystkich elementw potrzebnych do stworzenia typowej aplikacji, Spring Framework implementuje sprawdzone wzroce projektowe i zachca do ich stosowania. Dziki temu kod staje si przejrzysty i atwy do zrozumienia dla kadego, kto te wzorce zna, projekt jest doskonale udokumentowany dziki czemu mona bardzo atwo zrozumie zasad jego dziaania i pozna rwnie zaawansowane funkcje, wok projektu dziaa silna i prna spoeczno, zawsze gotowa do pomocy (listy mailingowe, forum dyskusyjne).

2.4. Zalety

14

ROZDZIA 3

Bean i kontener IoC


Gwnymi elementami Spring Framework, na bazie ktrych powstay i w ramach ktrych dziaaj wszystkie pozostae skadniki tej platformy s kontener IoC (ang. Inversion of Control ) i yjce wewntrz niego obiekty, zwane beanami. W rozdziale tym wyjani: co to s beany, jak je tworzy i jak z nich korzysta, jak deniowa zalenoci midzyobiektowe oraz jak mona wpywa na zachowanie beanw ju po ich utworzeniu. Do penego zrozumienia niniejszego rozdziau niezbdne jest posiadanie podstawowej wiedzy na temat nastpujcych zagadnie: specykacji JavaBeans, wzorca projektowego IoC oraz Singleton, lightweight containters, wstrzykiwania zalenoci przy pomocy konstruktorw i setterw. 15

3.1. Bean i fabryka beanw

16

3.1. Bean i fabryka beanw


Bean w rozumieniu Spring Framework to nic innego jak klasa zgodna ze specykacj JavaBeans. Zdaj sobie oczywicie spraw, e po tak dugim wprowadzeniu do tematu czytelnik oczekiwa czego bardziej spektakularnego, niemniej jednak taka wanie jest prawda. Aby zmiejszy, suszne poniekd, rozczarowanie spiesz doda, e taki stan rzeczy jest jednak bardziej zalet ni wad i to co najmniej z kilku powodw. Najwaniejsz zalet beanw w Spring Framework jest to, e mog to by absolutnie dowolne obiekty Java. Nie musz one implementowa adnego interfejsu, ani rozszerza adnej specycznej klasy bazowej wystarczy, e bd si trzyma znanej z JavaBeans konwencji nazewniczej metod. Dobrze napisane beany nie zale wic w aden sposb od Spring Framework. Raz napisne mona ponownie wykorzysta w innym rodowisku lub te uy cakowicie niezalenie jak kad inn klas. Kolejnym ogromnym plusem przyjtego przez autorw Spring Framework podejcia jest to, e bazuje ono na powszechnie przyjtym standardzie. Specykacja JavaBeans jest znana praktycznie kademu programicie, ktry zetkn si z jzykiem Java. Odpada wic konieczno uczenia si nowych zagadnie, wejcie w wiat Spring Framework nie powinno by dla nikogo ani problematyczne ani czasochonne. Ponadto, beany, z racji swej prostoty, doskonale uatwiaj praktyczne stosowanie, zyskujcego coraz wiksz popularno, programowania sterowanego testami (ang. test driven development). Tworzenie testw do beanw nie trwa dugo, podczas ich uruchamiania nie jest wymagana skomplikowana infrastruktura, a wikszo czasochonnych, i nie majcych bezporedniego wpywu na logik beanw operacji da si zasymulowa korzystajc z obiektw zastpczych, tzw. mock objects. Naley jednak pamita, e Spring Framework nie jest w stanie ochroni nas przed bdami projektowymi, jakie moemy popeni podczas tworzenia wasnych beanw. W dalszej czci tego rozdziau sprbujemy zlokalizowa czyhajce na programist puapki oraz poszuka sposobw ich uniknicia.

3.1. Bean i fabryka beanw

17

3.1.1. Deniowanie prostych beanw


Wiemy ju, e bean to dowolna klasa zgodna ze specykacj JavaBeans. Stwrzmy wic nasz pierwszy bean, ktry zrobi to, co kady szanujcy si pierwszy program powinien zrobi, czyli przywita si ze wiatem.
Listing 3.1. Pierwszy bean HelloWorld
1 2 3 4 5 6 7 } } public c l a s s H e l l o W o r l d { public void h e l l o ( ) { System . o u t . p r i n t l n ( W i t a j swiecie ! ); package p r z y k l a d y . r o z d z i a l 3 ;

Kolejnym krokiem jest poinformowanie Spring Framework o istnieniu naszej klasy. Framework obsuguje standardowo dwa formaty plikw konguracyjnych. Pierwszy z nich to XML, drugi to standardowy plik *.properties. Ten ostatni jest niemniej jednak bardzo mao popularny, dlatego te w dalszej czci ksiki wszystkie przykady bd zapisane wycznie w formacie XML. Dla naszego prostego przykadu plik konguracyjny moe wyglda nastpujco:
Listing 3.2. Minimalny plik konguracyjny w wersji XML
1 2 3 4 5 6 <b e a n s> <bean i d= h e l l o w o r l d c l a s s= p r z y k l a d y . r o z d z i a l 3 . H e l l o W o r l d /> </ b e a n s> <?xml versi on= 1 . 0 e n c o d i n g=UTF8 ?> < !D C Y E b e a n s PUBLIC //SPRING//DTD BEAN//EN O T P h t t p : //www. s p r i n g f r a m e w o r k . o r g / dtd / s p r i n g b e a n s . dtd >

Listing 3.3. Minimalny plik konguracyjny w wersji *.properties


1 h e l l o w o r l d . c l a s s=p r z y k l a d y . r o z d z i a l 3 . H e l l o W o r l d

Na najprostsz denicj beanu skadaj si: identykator oraz pena kwalikowana nazwa klasy. Identykator umoliwia jednoznaczne odwoanie si do konkretnego beanu. Nie pozostaje ju zatem nic innego, jak tylko zobaczy nasz bean w akcji. Poniszy kod tworzy dwie identyczne fabryki beanw: pierwsz na podstawie wpisw zawartych w pliku helloworld.xml, a drug na podstawie pliku

3.1. Bean i fabryka beanw

18

helloworld.properties. Nastpnie z fabryk pobierany jest nasz przykadowy bean, na ktrym mona ju bez przeszkd wywoywa metody biznesowe.
Listing 3.4. Przykad wykorzystania beanu HelloWorld
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 } } bean . h e l l o ( ) ; bean2 . h e l l o ( ) ; H e l l o W o r l d bean = ( HelloWorld ) xmlFactory . getBean ( h e l l o w o r l d ) ; H e l l o W o r l d bean2 = ( H e l l o W o r l d ) p r o p F a c t o r y . g e t B e a n ( h e l l o w o r l d ) ; // T w o r z e n i e fabryki na p o d s t a w i e pliku . pr o pe r tie s . DefaultListableBeanFactory p r o p F a c t o r y = new D e f a u l t L i s t a b l e B e a n F a c t o r y ( ) ; reader = // T w o r z e n i e fabryki na p o d s t a w i e p l i k u XML. XmlBeanFactory x m l F a c t o r y = new XmlBeanFactory ( x m l C o n f i g F i l e ) ; Resource xmlConfigFile = new C l a s s P a t h R e s o u r c e ( / p r z y k l a d y / r o z d z i a l 3 / h e l l o w o r l d . xml ) ; Resource propertiesConfigFile = new C l a s s P a t h R e s o u r c e ( / p r z y k l a d y / r o z d z i a l 3 / h e l l o w o r l d . p r o p e r t i e s ) ; public s t a t i c void main ( S t r i n g [ ] args ) { public c l a s s HelloWorldExample { import o r g . s p r i n g f r a m e w o r k . b e a n s . f a c t o r y . s u p p o r t . D e f a u l t L i s t a b l e B e a n F a c t o r y ; import o r g . s p r i n g f r a m e w o r k . b e a n s . f a c t o r y . s u p p o r t . P r o p e r t i e s B e a n D e f i n i t i o n R e a d e r ; import o r g . s p r i n g f r a m e w o r k . b e a n s . f a c t o r y . xml . XmlBeanFactory ; import o r g . s p r i n g f r a m e w o r k . c o r e . i o . C l a s s P a t h R e s o u r c e ; import o r g . s p r i n g f r a m e w o r k . c o r e . i o . R e s o u r c e ; package p r z y k l a d y . r o z d z i a l 3 ;

PropertiesBeanDefinitionReader

new P r o p e r t i e s B e a n D e f i n i t i o n R e a d e r ( p r o p F a c t o r y ) ; reader . loadBeanDefinitions ( propertiesConfigFile ) ;

Aby powyszy kod poprawnie si skompilowa i uruchomi naley doda do cieki klas archiwum spring.jar oraz pakiety zalene. Istnieje jeszcze trzeci sposb na utworzenie fabryki beanw, a mianowicie zapisanie jej konguracji bezporednio w kodzie Java.

Nieco wicej szczegw na temat beanw Spring Framework pozwala cile okreli natur i moment utworzenia konkretnego beanu. Ponisza denicja jest semantycznie zgodna z t z listingu 3.2. Odkrywa jednak kilka nowych szczegw.
Listing 3.5. Bardziej szczegowy plik konguracyjny
1 <bean

3.1. Bean i fabryka beanw

19

2 3 4 5 6

i d= h e l l o w o r l d c l a s s= p r z y k l a d y . r o z d z i a l 3 . H e l l o W o r l d name= w i t a j s w i e c i e s i n g l e t o n= t r u e l a z y i n i t = f a l s e />

Pojawiy si trzy nowe atrybuty: name, singleton oraz lazy-init. name podobnie jak id przypisuje beanowi unikatow nazw; przy pomocy tego atrybutu mona rwnie zdeniowa jeden lub wicej aliasw dla tego samego beana (aliasy oddziela naley przecinkiem lub rednikiem; spacje s ignorowane), singleton okrela natur beanu; jeeli warto tego atrybutu zostaa ustawiona na true (co jest wartoci domyln) kade pobranie danego beanu z fabryki zwrci zawsze referencj do jego pojedynczej instancji; warto false spowoduje tworzenie za kadym razem nowej instancji beana, lazy-init pozwala okreli, w ktrym momencie fabryka powinna utworzy pojedyncz instancj danego beanu; warto false (domylna) oznacza, e fabryka powinna utworzy instancj beanu od razu przy starcie; warto true powoduje odroczenie chwili utworzenia instancji obiektu tak dugo, jak to tylko moliwe, czyli do czasu pierwszego pobrania beanu z fabryki. Szczegln rozwag naley zachowa przy stosowaniu atrybutu singleton. Domylnie Spring Framework tworzy pojedyncze, wspdzielone instancje kadego beanu i w przewaajcej liczbie przypadkw jest to dziaanie podane. Taki bean podlega standardowemu cyklowi ycia i jest zarzdzany przez kontener. Inaczej wyglda sytuacja beanw zdeniowanych z opcj singleton=false. Rola Spring Framework sprowadza si wwczas do tworzenia obiektw i zwracania referencji do nich. Po spenieniu tego zadania kontener zapomina o ich istnieniu. Warto atrybutu lazy-init moe mie duy wpyw na czas uruchamiania fabryki. Ma to szczeglne znaczenie, gdy zdeniowane beany korzystaj z zasobw zewntrznych (np. nawizuj poczenia z baz danych) lub te

3.1. Bean i fabryka beanw

20

wykonuj przy starcie inne czasochonne czynnoci (np. obliczeniowe). Opcj leniwej inicjalizacji mona aktywowa globalnie dla caej fabryki poprzez dodanie atrybutu default-lazy-init="true" do elementu <beans> w pliku konguracyjnym. Wad takiego podejcia jest to, e Spring Framework nie zasygnalizuje tu po starcie fabryki ewentualnych bdw w konguracji naszych beanw. Jest to wic dobra opcja dla rodowiska produkcyjnego na etapie tworzenia systemu lepiej wyczy leniw inicjalizacj beanw, co pozwoli na szybsze wyapywanie ewentualnych bdw w konguracji. Uywajc atrybutu lazy-init moemy rwnie zapobiec tworzeniu przez fabryk instancji beanw, ktre nie powinny by tworzone, bo np. su tylko jako nadrzdne denicje dla innych beanw. Wicej na ten temat w dalszej czci tego rozdziau.

Edycja waciwoci beanw Kolejnym wanym zagadnieniem jest ustalenie stanu pocztkowego beanu. Beany powinno si pisa tak, aby bez wikszych, a najlepiej bez adnych zmian mona je byo ponownie wykorzyta, np. w innych projektach, dostosowujc tylko ustawienia konguracji. Konguracja nie powinna wic by zaszyta w kodzie klasy, lecz przekazana z zewntrz. Spring Framework oferuje bardzo prosty, a jednoczenie bardzo elastyczny mechanizm edycji waciwoci beanw bazujcy na specykacji JavaBeans. Wystarczy doda do beana publiczn metod ustawiajc pole, czyli tzw. setter. Listing 3.6 przedstawia prost klas z dwoma publicznymi metodami zgodnymi ze specykacj JavaBean.
Listing 3.6. Klasa bez konstruktora domylnego
1 2 3 4 5 6 7 8 9 10 11 12 13 public void setName ( S t r i n g name ) { t h i s . name = name ; } public void s e t V a l u e ( I n t e g e r this . value = value ; value ) { private Integer value ; p r i v a t e S t r i n g name ; public c l a s s SimpleSetter { package p r z y k l a d y . r o z d z i a l 3 ;

3.1. Bean i fabryka beanw

21

14 15 }

Pola value oraz name mona ustawi w pliku konguracyjnym fabryki w nastpujcy sposb:
Listing 3.7. Konguracja waciwoci beanw
1 2 3 4 <bean i d=mybean c l a s s= p r z y k l a d y . r o z d z i a l 3 . S i m p l e S e t t e r > <p r o p e r t y name= v a l u e > <v a l u e>5</ v a l u e> </ p r o p e r t y> <p r o p e r t y name=name> <v a l u e>H e l l o World !</ v a l u e> </ p r o p e r t y> </ bean>

Spring Framework automatycznie dokona konwersji podstawowych typw znajdujcych si w pakiecie .lang. Bardziej skomplikowane konwersje (w praktyce dowolne) s rwnie moliwe, ale wymagaj napisania rozszerzenia do kontenera. Zagadnieniu temu przyjrzymy si dokadniej w rozdziale 3.1.3. Uwaga! Zapis <value></value> nie oznacza ustawienia wartoci pola na null. Do tego celu suy specjalny element: <null/>.

Mapowanie kolekcji

Oprcz edycji typw prostych Spring Framework

umoliwia deniowanie w pliku konguracyjnym kolekcji obiektw, a w szczeglnoci: list, zbiorw, map oraz szczeglnego przypadku mapy obiektu java.util.Properties. Reprezentatywny plik konguracyjny mgby wyglda nastpujco:
Listing 3.8. Deniowanie kolekcji
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <bean i d=mybean c l a s s= C o l l e c t i o n E x a m p l e > <p r o p e r t y name= a l l o w e d > < l i s t> <v a l u e> 1 2 7 . 0 . 0 . 1</ v a l u e> <v a l u e>1 9 2 . 1 6 8 . 1 7 . 1 0 0</ v a l u e> </ l i s t> </ p r o p e r t y> <p r o p e r t y name= r o l e s > <map> <e n t r y key= bob > <v a l u e>admin</ v a l u e> </ e n t r y> <e n t r y key= s c o t t > <v a l u e>manager , s u p e r u s e r</ v a l u e> </ e n t r y> </map> </ p r o p e r t y> <p r o p e r t y name= c o u n t r i e s > <s e t> <v a l u e>p o l a n d</ v a l u e> <v a l u e>germany</ v a l u e> </ s e t> </ p r o p e r t y> <p r o p e r t y name= c o n f i g > <p r o p s> <prop key= s e n d . e m a i l > <v a l u e>t r u e</ v a l u e> prop> </ <prop key= app . name> <v a l u e>M y A p p l i c a t i o n</ v a l u e> prop> </

3.1. Bean i fabryka beanw

22

24 25 26

</ p r o p s> </ p r o p e r t y> </ bean>

W prawie wszystkich przypadkach kolekcje mona dowolnie zagnieda (np. mapa moe zawiera listy czy zbiory jako wartoci, etc.). Wyjtkiem jest tylko element <props> odpowiadajcy obiektowi java.util.Properties, ktry przyjmuje jako wartoci tylko acuchy tekstowe. Dla podanego przykadu klasa beanu musi zawiera nastpujce sygnatury metod 1 :
Listing 3.9. Metody zgodne ze specykacj JavaBean
1 2 3 4 void s e t A l l o w e d ( j a v a . u t i l . L i s t void s e t C o u n t r i e s ( j a v a . u t i l . S e t allowed ) ; countries ); configuration ); void s e t R o l e s ( j a v a . u t i l . Map r o l e s ) ; void s e t C o n f i g ( j a v a . u t i l . P r o p e r t i e s

Mapowanie dowolnych beanw jako waciwoci innych beanw Mapowanie typw prostych i kolekcji to za mao, by osign wszystkie cele. Moe si zdarzy, e zapragniemy utworzy i przekaza do beanu dowolny obiekt. Na przykad obiekt moe zawiera metod setConfiguration(Configuration config), gdzie Configuration, to specjalna klasa, ktra oprcz przechowywania stanu konguracji robi jeszcze kilka innych poytecznych rzeczy. Twrcy Spring Framework przewidzieli tak ewentualno i w prawie kadym miejscu pliku konguracyjnego (wyjtek stanowi wspomniany ju element <props>), w ktrym wskazuje si warto mona wstawi denicj nowego beana. Ilustruje to listing 3.10.
Listing 3.10. Zagniedony bean
1 2 3 4 5 6 7 8 9 10 11 <bean i d=mybean c l a s s= A p p l i c a t i o n > <p r o p e r t y name= c o n f i g u r a t i o n > <bean c l a s s= C o n f i g u r a t i o n > <p r o p e r t y name= p r o p e r t i e s > <p r o p s> <prop key= v a l u e 1 > <v a l u e>t r u e</ v a l u e> prop> </ <prop key= v a l u e 2 > <v a l u e> f a l s e</ v a l u e> prop> </ </ p r o p s> </ p r o p e r t y> </ bean> </ p r o p e r t y> 1

Dobr praktyk jest uywanie interfejsw w metodach ustawiajcych pola zamiast

konkretnych klas. Pozwala to na nieinwazyjn zmian implementacji przekazywanych obiektw.

3.1. Bean i fabryka beanw

23

12

</ bean>

Ostatni wan kwesti dotyczc konguracji beanw jest przekazywanie w metodzie ustawiajcej referencji do ju utworzonego beanu. Zagadnienie zostanie poruszone dalszej czci rozdziau, przy okazji omawiania kontenera IoC (rozdz. 3.2).

3.1.2. Cykl ycia


Tworzc nowe beany fabryka wykonuje pewne czynnoci w dokadnie zdeniowanej kolejnoci. Cykl ycia beanu, bo o nim mowa, jest w Spring Framework bardzo prosty i skada si z kilku nastpujcych po sobie etapw: 1. Utworzenie instancji. 2. Ustawienie wartoci pocztkowych pl. 3. Inicjacja. 4. wiadczenie usug przez bean. 5. Zamknicie beanu. 6. Usunicie instancji z fabryki. Uwaga! Powyszy cykl ycia dotyczy tylko beanw dziaajcych w trybie pojedynczej instancji (singleton=true). Jeeli bean nie jest pojedyncz instancj cykl ycia koczy si na etapie inicjalizacji, po przeprowadzeniu ktrej kontener zapomina o istnieniu nowoutworzonego obiektu. Spring Framework automatycznie kontroluje wszystkie fazy cyklu ycia, co w przypadku nieskomplikowanych i mao wymagajcych beanw jest jak najbardziej podane. Niekiedy zachodzi jednak potrzeba przeprowadzenia dodatkowych czynnoci na etapie inicjalizacji (np. sprawdzenie konguracji) czy zamykania beanu (np. zapisanie aktualnego stanu konguracji beanu). Wanie te dwa etapy cyklu ycia mona zdeniowa samodzielnie. Mona to zrobi na dwa sposoby:

3.1. Bean i fabryka beanw

24

implementujc specjalne interfejsy dostarczone przez Spring Framework, wskazujc w pliku konguracyjnym nazwy metod, ktre maj posuy do inicjalizacji i zamknicia beanu.

Interfejsy wpywajce na cykl ycia Spring Framework dostarcza dwa interfejsy, ktre bean moe zaimplementowa, aby wpyn na swj cykl ycia. S to:

org.springframework.beans.factory.InitializingBean oraz org.springframework.beans.factory.DisposableBean.

Pierwszy z nich, InitializingBean (listing 3.11), deniuje jedn metod, ktra zostatnie wykonana w momencie pierwszego pobrania beanu z kontenera. Metoda ta moe i powinna rzuci wyjtek, jeeli okae si, e bean nie jest gotowy do wiadczenia usug.
Listing 3.11. Interfejs InitializingBean
1 void a f t e r P r o p e r t i e s S e t ( ) throws j a v a . l a n g . E x c e p t i o n ;

Interfejs DisposableBean (listing 3.12) rwnie skada si z pojedynczej metody, ktr bean musi zaimplementowa. Metoda destroy() zostanie wykonana w momencie zamykania fabryki i powinna skutkowa zwolnieniem wszystkich zasobw uywanych przez bean. Moe ona rzuci wyjtek, jeeli zamknicie beanu nie jest moliwe. Wyjtek taki zostanie zapisany w dzienniku systemowym, po czym zostanie zignorowany, tj. nie spowoduje nagego zatrzymania/zniszczenia caej fabryki.
Listing 3.12. Interfejs DisposableBean
1 void d e s t r o y ( ) throws j a v a . l a n g . E x c e p t i o n ;

3.1. Bean i fabryka beanw Deklaratywne opisanie cyklu ycia

25

Uywanie interfejsw do zasygnalizowania chci ingerencji w cykl ycia beanu ma jedn zasadnicz wad. Kod beanu staje si cakowicie zaleny od Spring Framework. Nie jest moliwe wykorzystanie tak napisanego beanu w innym rodowisku bez dokonania stosownych zmian w kodzie. Dla wszystkich osb, ktre wolayby zachowa niezaleno beanw od Spring Framework autorzy tej platformy przewidzieli alternatywny sposb. Mona umieci nazwy metod w pliku konguracyjnym, zostan one wywoane przez Spring Framework za pomoc mechanizmu odbicia (ang. reection).
Listing 3.13. Deklaratywne deniowanie cyklu ycia
1 2 3 4 5 <bean i d= b e a n i d c l a s s= SampleBean i n i t method= i n i t i a l i z e d e s t r o y method= d e s t r o y />

Metody okrelone przez argumenty init-method oraz destroy-method nie powinny zwraca adnej wartoci, ale mog deklarowa rzucanie dowolnego wyjtku, czyli podlegaj dokadnie tym samym reguom, co metody z interfejsw InitializingBean oraz DisposableBean.

3.1.3. Niestandardowe edytory waciwoci


Przedstawione do tej pory moliwoci kontenera Spring Framework pozwol na utworzenie dowolnego beanu. Pora przyjrze si bardziej zaawansowanym zagadnieniom, ktre pozwol wykorzysta maksimum moliwoci tkwicych w Spring Framework. Pierwszym z nich jest moliwo deniowania wasnych edytorw waciwoci. Spring Framework umoliwia automatyczn konwersj podstawowych typw, takich jak liczby, czy acuchy tekstowe. A co w przypadku np. dat czy innych bardziej zoonych obiektw? Czy mona np. automatycznie dokona konwersji acucha tekstowego na dat? Odpowied brzmi: tak! Wystarczy napisa wasny specjalizowany edytor waciwoci i przekaza jego referencj fabryce beanw. Zaraz si okae, e mimo do gronie brzmicej nazwy nie jest to wcale skomplikowane.

3.1. Bean i fabryka beanw

26

Zamy, e chcemy doda do fabryki moliwo automatycznej konwersji acuchw w formacie YYYY-MM-DD na daty. Konguracja beana wygldaaby nastpujco:
Listing 3.14. Przykad konguracji beanu z polem typu java.util.Date
1 2 3 4 5 <bean i d=mybean c l a s s= p r z y k l a d y . r o z d z i a l 3 . CustomEditorSample > <p r o p e r t y name= d a t e > <v a l u e>20041012</ v a l u e> </ p r o p e r t y> </ bean>

czyli dokadnie tak samo jak kada inna. Bean z kolei posiadaby nastpujc metod ustawiajc pole date:
Listing 3.15. Metoda ustawiajca pole date
1 void s e t D a t e ( j a v a . u t i l . Date d a t e ) ;

Spring Framework nie potra automatycznie przekonwertowa wartoci typu java.lang.String do typu java.util.Date. Naley wic rozszerzy moliwoci fabryki o tak funkcj. Robi si to poprzez zarejestrowanie wasnego edytora tu po utworzeniu fabryki, a przed pobraniem z niej beanw. Poniszy przykad rejestruje jeden edytor, ktry pozwala edytowa pola typu java.util.Date o ustalonym formacie.
Listing 3.16. Rejestrowanie wasnych edytorw waciwoci
1 2 3 4 5 6 7 Resource config = new C l a s s P a t h R e s o u r c e ( p r z y k l a d y / r o z d z i a l 3 / c u s t o m e d i t o r . xml ) ; XmlBeanFactory b f = new XmlBeanFactory ( c o n f i g ) ; b f . r e g i s t e r C u s t o m E d i t o r ( j a v a . u t i l . Date . c l a s s , new CustomDateEditor ( new SimpleDateFormat ( yyyy dd ) , true ) ) ; MM CustomEditorSample bean = ( CustomEditorSample ) b f . g e t B e a n ( mybean ) ;

Metoda registerCustomEditor() wymaga podania dwch argumentw: typu, ktry chcemy edytowa musi to by ten sam typ, ktry przyjmuje metoda ustawiajca pole, edytor, implementujcy interfejs java.beans.PropertyEditor. Mechanizm rejestrowania edytorw jest wic bardzo elastyczny i umoliwia dokonywanie konwersji dowolnych acuchw tekstowych na obiekty i odwrotnie.

3.1. Bean i fabryka beanw

27

3.1.4. Bean bez domylnego konstruktora


Beanem moe by dowolna klasa. W szczeglnoci Spring Framework nie wymaga obecnoci konstruktora domylnego. Zamieszczona na listingu 3.17 klasa nie posiada konstruktora domylnego. Aby Spring Framework mg utworzy instancj tej klasy naley w pliku konguracyjnym zdeniowa argumenty konstruktora tak jak na listingu 3.18.
Listing 3.17. Klasa bez konstruktora domylnego
1 2 3 4 5 6 } } public c l a s s NoDefaultContructor { Integer count ) { public N o D e f a u l t C o n t r u c t o r ( S t r i n g name , t h i s . name = name ; this . count = count ;

Listing 3.18. Konguracja kontruktora


1 2 3 4 5 6 7 8 <bean i d=mybean c l a s s= p r z y k l a d y . r o z d z i a l 3 . N o D e f a u l t C o n t r u c t o r > <c o n s t r u c t o r a r g t y p e= j a v a . l a n g . S t r i n g i n d e x= 0 > <v a l u e>H e l l o World !</ v a l u e> </ c o n s t r u c t o r a r g> <c o n s t r u c t o r a r g t y p e= j a v a . l a n g . I n t e g e r i n d e x= 1 > <v a l u e>10</ v a l u e> </ c o n s t r u c t o r a r g> </ bean>

Element <constructor-arg> moe zawiera dwa opcjonalne atrybuty: type czyli pen nazw typu parametru, index czyli nieujemn liczb okrelajc, ktrego parametru denicja dotyczy. Mona pomin powysze atrybuty, jeeli da si jednoznacznie rozpozna argumenty, czyli w przypadku, gdy s one rnych typw. Element constructor-arg moe zawiera dowolny element spord value, list, map, set, properties, bean, null, a take referencje do innych beanw.

3.1.5. Tworzenie beanw przy pomocy fabryki


Niekiedy wygodniej jest nie tworzy beanw bezporednio lecz za porednictwem fabryk. Moe to by rwnie przydatne na przykad w sytuacji, gdy

3.1. Bean i fabryka beanw

28

instancji beanu nie da si z pewnych powodw utworzy bezporednio (np. klasa, ktra ma by beanem nie jest zgodna ze standardem JavaBeans). Spring Framework oferuje stosowanie fabryk beanw na dwa sposoby: poprzez implementacj interfejsu FactoryBean, poprzez uycie atrybutw factory-bean oraz factory-method w pliku konguracyjnym.

Interfejs org.springframework.beans.factory.FactoryBean Bean, ktry implementuje interfejs FactoryBean jest traktowany przez Spring Framework jako szczeglny rodzaj beanu. W tym przypadku kontener tworzy instancj beanu, ale nie zwraca referencji do niej lecz zleca jej zadanie utworzenia obiektu docelowego. Interfejs ten deniuje trzy metody:
Listing 3.19. Interfejs org.springframework.beans.factory.FactoryBean
1 2 3 O b j e c t g e t O b j e c t ( ) throws E x c e p t i o n ; Class getObjectType ( ) ; boolean i s S i n g l e t o n ( ) ;

Metoda getObject() zwraca docelowy obiekt utworzony przez fabryk. Metoda getObjectType() zwraca typ docelowego obiektu, ale moe te zwrci warto null, jeeli fabryka nie jest w stanie zidentykowa typu przed utworzeniem obiektu docelowego. Ostatnia metoda, isSingleton() wskazuje, czy bean ma by jedn wspdzielon instancj, czy te fabryka za kadym razem powinna utworzy nowy obiekt.

Atrybuty factory-bean i factory-method Alternatyw dla interfejsu FactoryBean stanowi dopisanie do denicji beanu dodatkowych informacji wskazujcych na fabryk. Poniszy przykad zawiera dwie denicje beanw, ktre s tworzone przez fabryki.
Listing 3.20. Fabryki beanw
1 2 3 4 < ! f a b r y k a 1 > <bean i d= bean1 c l a s s= Bean

3.1. Bean i fabryka beanw

29

5 6 7 8 9 10 11 12

f a c t o r y method= c r e a t e O b j e c t > < ! f a b r y k a 2 > <bean i d= f a c t o r y B e a n c l a s s= F a c t o r y B e a n /> <bean i d= bean2 f a c t o r y bean= f a c t o r y B e a n f a c t o r y method= c r e a t e O b j e c t />

Klasa Bean w fabryce 1 musi posiada statyczn metod createObject() zwracajc docelowy obiekt. Typ obiektu moe by dowolny, w szczeglnoci nie musi to by typ wskazany przez atrybut class. Jeeli jest to ten sam typ to metod tworzc mona traktowa jako alternatyw dla konstruktora. Metoda wskazana w atrybucie factory-method moe przyjmowa dowoln ilo argumentw. Konguruje si je za pomoc poznanego ju elementu constructor-arg, dokadnie w ten sam sposb, jak klasy bez konstruktora domylnego, z tym wyjtkiem, e nie dziaa w tym przypadku automatyczne dopasowywanie beanw (zagadnienie to omwione zostanie szerzej przy okazji prezentacji kontenera IoC). Fabryka 2 dziaa podobnie, jednak tworzenie instancji beanu nie nastpuje w tej samej klasie w wyniku wywoania statycznej metody, lecz jest delegowane do innego beanu. Fabryka jest wic w tym przypadku zwykym beanem, ktry posiada, ju niestatyczn, metod createObject.

Interfejs FactoryBean czy atrybuty? Poniewa Spring Framework oferuje dwa alternatywne mechanizmy stosowania fabryk zasadnym wydaje si pytanie: ktry stosowa i jakich sytuacjach? Jeeli moemy sobie pozwoli na zaleno od API Spring Framework w naszym projekcie to najwygodniej jest uy interfejsu FactoryBean. Wszystkie rozszerzenia Spring Framework stosuj wanie to podejcie. W innym przypadku lepiej zda si na atrybuty factory-method i factory-bean.

3.2. Kontener IoC

30

3.1.6. Relacje dziedziczenia

3.2. Kontener IoC

Z lektury poprzedniego rozdziau wiemy ju sporo o beanach, ich powstawaniu, naturze i cyklu ycia. Kolejnym fundamentalnym elementem platformy Spring Framework jest kontener IoC umoliwiajcy deniowanie wzajemnych relacji midzy beanami. O relacji czy zalenoci midzy obiekami (beanami) mona mwi wtedy, gdy jeden bean wymaga do prawidowego funkcjonowania innego obiektu. IoC, czyli Inversion of Control to wzorzec projektowy umoliwiajcy realizacj zalenoci midzy obiektami niejako bez wiedzy o tym fakcie samych zainteresowanych. IoC realizuje si najczciej poprzez wstrzykiwanie zalenoci (ang. dependency injection) umieszczajc uprzednio obiekty w specjalnym kontenerze. Kontener sam potra poprawnie dopasowa wszystkie zalenoci i skongurowa obiekty przed udostpnieniem ich uytkownikowi. Wicej na temat wzorca IoC mona poczyta w moim artykule Wprowadzenie do lightweight containers opublikowanym w portalu JDN (http://jdn.pl/node/1). Spring Framework zawiera bardzo wygodn w uyciu implementacj kontenera IoC. Springowy kontener IoC jest sercem caej plaformy, wszystkie pozostae elementy z niego korzystaj. Co wane kontener IoC w Spring Framework jest rwnie dostpny w postaci samodzielnej biblioteki, ktr mona zaintegrowa z wasnym projektem bez koniecznoci korzystania z caego frameworka. W takim przypadku Spring Beans (w postaci archiwum jar o rozmiarze nieco wikszym ni 200Kb) stanowi doskona alternatyw dla innych dostpnych na rynku kontenerw IoC (Picocontainer, HiveMind). Kontener IoC w Spring Framework jest nazywany rwnie fabryk beanw. Te dwie nazwy stosowane bd w niniejszej ksice wymiennie.

3.2. Kontener IoC

31

3.2.1. Deniowanie zalenoci midzy beanami


Istnieje kilka metod speniania zalenoci midzy obiektami, takich jak wyszukiwanie obiektw (ang. lookup), wstrzykiwanie zalenoci przy pomocy konstruktorw, setterw czy pl. Kontener IoC w Spring Framework implementuje dwa sposoby wstrzykiwania zalenoci: za pomoc setterw (ang. setter injection), za pomoc konstruktorw (ang. constructor injection). Kade z tych podej ma swoje wady i zalety, kade ma swoich zwolennikw i przeciwnikw. Nie chcc wzbudza witych wojen poprzestamy na ustaleniu, e wszdzie stosowa bdziemy takie podejcie, ktre bdzie dla nas w danej chwili bardziej intuicyjne i po prostu wygodniejsze. Przyjrzyjmy si jak wyglda w Spring Framework wstrzykiwanie zalenoci. Niech za przykad posu nam dwa proste beany NameProvider oraz NameWriter o nastpujcej postaci:
Listing 3.21. Przykadowe beany - NameProvider
1 2 3 4 5 6 7 } } public c l a s s NameProvider { public S t r i n g provideName ( ) { return Janek ; package p r z y k l a d y . r o z d z i a l 3 ;

Listing 3.22. Przykadowe beany - NameWriter


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public void writeName ( ) { System . o u t . p r i n t l n ( n a m e P r o v i d e r . provideName ( ) ) ; } public void s e t N a m e P r o v i d e r ( NameProvider n a m e P r o v i d e r ) { t h is . nameProvider = nameProvider ; } public NameWriter ( NameProvider n a m e P r o v i d e r ) { setNameProvider ( nameProvider ) ; public NameWriter ( ) {} p r i v a t e NameProvider n a m e P r o v i d e r ; public c l a s s NameWriter { package p r z y k l a d y . r o z d z i a l 3 ;

3.2. Kontener IoC

32

19 20 }

Widzimy wic, e klasa NameWriter korzysta z klasy NameProvider w celu pobrania imienia. Jak zapisa t zaleno w Spring Framework?

Wstrzykiwanie zalenoci za pomoc setterw Pierwszym omwionym sposobem wstrzykiwania zalenoci jest wykorzystanie setterw, czyli metod ustawiajcych dane pole. W tym przypadku konguracja beanw powinna wyglda nastpujco (dla czytelnoci pominito deklaracj DTD):
Listing 3.23. Wstrzykiwanie zalenoci przy pomocy setterw
1 2 3 4 5 6 <b e a n s> <bean i d= n a m e P r o v i d e r c l a s s= p r z y k l a d y . r o z d z i a l 3 . NameProvider /> <bean i d= nameWriter c l a s s= p r z y k l a d y . r o z d z i a l 3 . NameWriter > <p r o p e r t y name= n a m e P r o v i d e r > r e f < </ bean> </ b e a n s> bean= n a m e P r o v i d e r /> </ p r o p e r t y>

W linijce 4 uywajc elementu <ref bean="nameProvider"/> informujemy kontener, e w trakcie tworzenia beana o nazwie nameWriter powinien przekaza do settera o nazwie nameProvider (czyli konretnie do metody setNameProvider()) beana o nazwie nameProvider. Jeli bean nameProvider nie zosta wczeniej utworzony kontener utworzy go i zainicjuje automatycznie. Mona sprawdzi dziaanie wstrzykiwania zalenoci przez settery uruchamiajc przykad przyklady.rozdzial3.SetterInjectionExample.

Wstrzykiwanie zalenoci za pomoc konstruktorw Przeledmy teraz ten sam przykad, ale zamiast setterw uyjmy argumentu konstruktora do przekazania referencji do obiektu zalenego.
Listing 3.24. Wstrzykiwanie zalenoci przy pomocy konstruktorw
1 2 3 4 5 <b e a n s> <bean i d= n a m e P r o v i d e r c l a s s= p r z y k l a d y . r o z d z i a l 3 . NameProvider /> <bean i d= nameWriter c l a s s= p r z y k l a d y . r o z d z i a l 3 . NameWriter > <c o n s t r u c t o r a r g> r e f < </ bean> bean= n a m e P r o v i d e r /> </ c o n s t r u c t o r a r g>

3.2. Kontener IoC

33

</ b e a n s>

Element <constructor-arg> suy wanie do ustawiania argumentw konstruktora. Jeli konstruktor miaby wicej ni jeden argument to oczywicie naley dla kadego z nich stworzy odpowiedni wpis <constructor-arg>. Wstrzykiwanie zalenoci za pomoc konstruktorw demonstruje klasa przyklady.rozdzial3.ContructorInjectionExample. Efekt dziaania wstrzykiwania zalenoci przez konstruktor z pozoru niczym nie rni si od poprzedniego przykadu, w ktrym uyto do tego celu metod ustawiajcy pola. I w jednym i w drugim przykadzie zosta osignity ten sam cel obiekt NameWriter otrzyma referencj do obiektu NameProvider. Niemniej jednak warto wspomnie o pewnej istotnej rnicy wynikajcej z zastosowania innego sposobu wstrzykiwania zalenoci. Ot uywajc wstrzykiwania zalenoci za pomoc konstruktorw moemy mie pewno, e bean, ktrego chcemy uy zosta poprawnie zainicjowany. Jeli np. nie byoby konstruktora domylnego w klasie a programista zapomniaby doda odpowiedniego elementu <constructor-arg> do pliku konguracyjnego to obiekt w ogle nie zostaby utworzony. Wirtualna maszyna zgosiaby stosowny wyjtek i kontener IoC w ogle by nie wystartowa. W przypadku wstrzykiwania zalenoci za pomoc setterw obiekt zostaby utworzony, kontener IoC funkcjonowaby z pozoru poprawnie, a o bdnej konguracji zostalibymy poinformowani dopiero podczas prby wywoania metody biznesowej le skongurowanego beanu. O tym jak radzi sobie ze sprawdzaniem i zapewnieniem poprawnej konguracji beanw w dalszej czci tego rozdziau.

Co potra, a czego nie kontener IoC? W powyszym prostym przykadzie sytuacja bya wrcz komfortowa. Dwa beany prosta zaleno. Taki scenariusz jednak daleko odbiega od typowego zastosowania. Czsto zalenoci s duo bardziej zawie, kaskadowe, jeden bean czsto wymaga do poprawnego funkcjonowania wiele innych beanw.

3.2. Kontener IoC

34

Spring Framework umoliwia zdeniowanie prawie dowolnych zalenoci midzy obiektami. Jedynym wyjtkiem s zalenoci cykliczne, gdy bean A zaley od beana B i jednoczenie bean B zaley od beana A. Takiej sytuacji kontener IoC w Spring Framework nie potra obsuy, ale potra j wykry i zasygnalizowa bd w konguracji.

3.2.2. Sprawdzanie poprawnoci konguracji beanw


Poprawne skongurowanie beanw to klucz do prawidowego dziaania aplikacji. Nic nie jest bardziej frustrujce dla programisty jak nagle pojawiajce si w logach java.lang.NullPointerException. . . Jak broni si przed takimi sytuacjami? Bdy literowe s mao dokuczliwe, gdy zostan wyapane ju na etapie przetwarzania pliku XML przez parser oraz tworzenia denicji beanw przez kontener IoC Spring Framework. Wicej kopotu moe sprawia dodanie nowego settera do beana bez dodania odpowiedniego wpisu w pliku konguracyjnym. Tego typu bdu nie da si wykry na etapie uruchamiania kontenera. W efekcie otrzymamy bean, ktry co prawda zosta utworzony, ale kontener nie ustawi w nim wszystkich pl i tym samym bean taki nie jest w stanie prawidowo realizowa swoich zada. Przed tak sytuacj mona obroni si na dwa sposoby. Pierwszy z nich to rezygnacja ze wstrzykiwania zalenoci za pomoc setterw i uywanie do tego celu jedynie konstruktorw. Pomyki zostan wychwycone od razu na etapie tworzenia obiektu. Sposb ten jest z jednej strony niezawodny, ale z drugiej bywa do niewygodny, zwaszcza jak zalenoci jest duo. Trudno nazwa przejrzystym i adnym konstruktor, ktry ma np. dziesi, czy wicej argumentw. . . Spring Framework dostarcza alternatywne rozwizanie umoliwiajce sprawdzenie poprawnoci beana po jego utworzeniu. poznalimy je ju przy okazji omawiania cyklu ycia beanw w rozdziale 3.1.2. Przypomnijmy: implementujc interfejs InitializingBean lub dodajc do denicji beana

3.2. Kontener IoC

35

atrybut init-method moemy sprawdzi, czy wszystkie pola zostay poprawnie ustawione i czy bean jest gotowy do wiadczenia usug. Jeli tak nie jest to mamy szans zgosi stosowny wyjtek. Bardzo wczenie (na etapie tworzenia kontenera) jestemy wic w stanie wykry braki w konguracji.

3.2.3. Automatyczne dopasowywanie zalenoci


Tworzenie pliku konguracyjnego fabryki beanw jest do uciliwe, zwaszcza w przypadku duych fabryk zarzdzajcych np. kilkudziesicioma zalenymi beanami. Liczba beanw pomnoona przez liczb waciwoci, ktre naleaoby zadeklarowa moe przeoy si na bardzo duy plik XML, ktry jest trudny do edycji. Pojawia si wic oczywiste pytanie, czy nie da si uproci pliku konguracyjnego? Czy np. dopasowywanie zalenoci nie mogoby si odbywa automatycznie, tak jak ma to miejsce np. w przypadku innego popularnego kontenera IoC Picocontainera? Spring Framework jest pod tym wzgldem bardzo elastyczny i oferuje moliwo automatycznego wyszukiwania obiektw zalenych w fabryce. Mona tego dokona na kilka sposobw: beany mona dopasowywa na podstawie ich nazw, beany mona dopasowywa na podstawie ich typw, beany mona dopasowywa na podstawie ich konstruktorw.

Automatyczne dopasowywanie beanw na podstawie nazw Pierwszy sposb automatycznego dopasowywania beanw opiera si na bardzo prostym zaoeniu. Jeeli jeden bean posiada waciwo xxx w myl specykacji Java Beans (czyli posiada publiczn metod void setXxx()), to kontener IoC poszuka beana o nazwie xxx i przekae referencj do niego. To najprostszy i chyba najbardziej intuicyjny sposb automatycznego deniowania zalenoci. W pliku konguracyjnym wyglda to nastpujco:
Listing 3.25. Dopasowywanie zalenoci wg nazwy

3.2. Kontener IoC

36

1 2 3 4

<b e a n s> <bean i d= n a m e P r o v i d e r c l a s s= p r z y k l a d y . r o z d z i a l 3 . NameProvider /> <bean i d= nameWriter c l a s s= p r z y k l a d y . r o z d z i a l 3 . NameWriter a u t o w i r e=byName /> </ b e a n s>

Klasa NameWriter posiada publiczn metod setNameProvider(), zastosowalimy dopasowanie wg nazwy (atrybut autowire="byName"), dlatego te kontener poszuka wrd beanw jednego o nazwie nameProvider, zainicjuje go i przekae referencj do niego beanowi NameWriter.

Automatyczne dopasowywanie beanw na podstawie typu Innym typem automatycznego dopasowywania beanw jest dopasowywanie ich na podstawie typu. Listing 3.26 przedstawia przykadow konguracj:
Listing 3.26. Dopasowywanie zalenoci wg typu
1 2 3 4 <b e a n s> <bean i d= dowolnaNazwa c l a s s= p r z y k l a d y . r o z d z i a l 3 . NameProvider /> <bean i d= nameWriter c l a s s= p r z y k l a d y . r o z d z i a l 3 . NameWriter a u t o w i r e= byType /> </ b e a n s>

Atrybut autowire="byType" informuje fabryk beanw, e powinna ona poszuka w klasie NameWriter wszytkich publicznych metod ustawiajcych, sprawdzi typy argumentw, jakie te metody przyjmuj, a nastpnie wyszuka pasujce do tych typw beany zadeklarowane w kontenerze. Dopasowywanie na podstawie typu ma jedn zasadnicz wad: moe by stosowane tylko w przypadku, gdy mamy pewno, e istnieje tylko jeden bean szukanego typu. Jeli jest ich wicej kontener zgosi wyjtek i zakoczy prac.

Automatyczne dopasowywanie beanw na podstawie konstruktorw Trzecim typem automatycznego dopasowywania beanw jest wyszukiwanie ich na podstawie argumentw konstruktora. Zasada dziaania jest tu analogiczna do dopasowywania wg typu, z tym jednak wyjtkiem, e pod uwag brane s argumenty konstruktorw zamiast setterw. Listing 3.27 zawiera przykadow konguracj:

3.2. Kontener IoC


Listing 3.27. Dopasowywanie zalenoci wg konstruktorw
1 2 3 4 5 <b e a n s> <bean i d= n a m e P r o v i d e r c l a s s= p r z y k l a d y . r o z d z i a l 3 . NameProvider /> <bean i d= nameWriter c l a s s= p r z y k l a d y . r o z d z i a l 3 . NameWriter a u t o w i r e= c o n s t r u c t o r /> </ b e a n s>

37

Peen automat Spring Framework oferuje rwnie jeden specjalny tryb automatycznego wyszukiwania zalenoci. Jeli warto atrybutu autowire ustawimy na autodetect to kontener sprbuje dobra optymaln metod szukania zalenoci. Algorytm przedstawia si nastpujco: jeli klasa nie posiada domylnego konstruktora to zalenoci dopasowywane s na podstawie dostpnego konstruktora, jeli klasa posiada kilka konstruktorw to wybierany jest ten z najwiksz iloci atrybutw, jeli natomiast klasa posiada domylny konstruktor to stosowana jest metoda automatycznego dopasowywania zalenoci na podstawie typu (autowire="byType").

Domylna polityka autodopasowania Z przytoczonych przykadw wynika, e atrybut autowire naley doda do kadego beana, ktrego autodopasowanie ma dotyczy. Domyln polityk Spring Framework jest cakowity brak autodopasowania (atrybut autowire przyjmuje warto no). Jeli chcielibymy, aby wszystkie beany w kontenerze podlegay np. regule autodopasowywania wg nazwy powinnimy przy kadej deklaracji beanu umieci atrybut autowire i nada mu podan warto. Rczne przerabianie caego pliku konguracyjnego mogoby by do monotonne i czasochonne. Autorzy Spring Framework przewidzieli wic moliwo ustawienia domylnej polityki autodopasowania dla caego kontenera. Wystarczy ustawi atrybut default-autowire gwnego elementu

3.2. Kontener IoC

38

beans nadajc mu jedn warto z no, byName, byType, constructor lub autodetect. Np.:
Listing 3.28. Domylna polityka autodopasowania
1 2 3 4 <b e a n s d e f a u l ta u t o w i r e=byName> <bean i d= n a m e P r o v i d e r c l a s s= p r z y k l a d y . r o z d z i a l 3 . NameProvider /> <bean i d= nameWriter c l a s s= p r z y k l a d y . r o z d z i a l 3 . NameWriter /> </ b e a n s>

spowoduje, e wszystkie beany bd podlega regule dopasowywania zalenoci wg nazwy.

Stosowa autodopasowywanie czy nie? Autorzy Spring Framework nie polecaj stosowania mechanizmu automatycznego dopasowywania zalenoci. Mimo kilku niewtpliwych zalet (znaczne zmniejszenie wielkoci pliku XML, czy brak koniecznoci wprowadzania zmian w pliku XML w przypadku zmiany sygnatury konstruktora, czy dodania nowych setterw) stosowanie autodopasowania moe wprowadzi sporo zamieszania. Przede wszystkim nie jest oczywiste dla czytajcego tak skonstruowany plik konguracyjny. Aby zrozumie zalenoci midzy beanami trzeba zajrze do kodu. Oczywist prawd jest, e prosty, zrozumiay, intuicyjny i samodokumentujcy si kod to klucz do sukcesu projektu w duszej perspektywie. Automatyczne dopasowywanie wprowadza do projektu swego rodzaju magi - co si dzieje, ale nie wida dlaczego. Oczywicie istniej sytuacje, gdzie stosowanie autodopasowywania jest wrcz wskazane. S to przede wszytkim mae projekty (prototypy), ktre pisze si szybko i wprowadza czste zmiany w kodzie. Autodopasowywanie uwalnia wtedy programist od koniecznoci czstej rcznej modykacji pliku XML. Z dowiadczenia mog powiedzie, e cakiem niele sprawdza si dopasowywanie wg nazwy. Przede wszystkim dlatego, e wymusza pewn konwencj nazewnicz (nazwa beana musi by tosama z setterem), co zapewnia, e kod staje si bardzo intuicyjny - wiemy, czego si spodziewa i gdzie. Jeli dodatkowo zastosuje si samoopisujce si nazwy setterw (np.

3.2. Kontener IoC

39

nameProvider zamiast nProv) to czytelny pozostanie zarwno kod, jak i plik konguracyjny. Problematyczne natomiast moe okaza si dowizywanie wg typu, poniewa na jakim etapie prac nad projektem moe si zdarzy, e pojawi si dwa lub wicej beany tego samego typu. To z kolei doprowadzioby pewnie do sytuacji, w ktrej autodopasowanie stosowane by byo dla wikszoci beanw (bo tak np. ustawiona byaby domyla polityka autowire), a dla kilku naleaoby zdeniowa zalenoci explicite. Czytelno takiego pliku drastycznie si pogarsza. Jak w kadym przypadku zoty rodek naley znale samemu. Pocztkujcym uytkownikom Spring Framework zalecam nie korzystanie z mechanizmu autodopasowania.

3.2. Kontener IoC

40

ROZDZIA 4

Programowanie aspektowe w Spring Framework

Co jaki czas pojawiaj si w informatyce przeomowe koncepcje, ktre rzucaj zupenie nowe wiato na dotychczas stosowane rozwizania. Jednym z wikszych skokw jakociowych ostatnich lat jest, zdaniem autora i nie tylko, programowanie aspektowe (ang. AOP - Aspect Oriented Programming). Pozwala ono spojrze na program w kategoriach powtarzajcych si zada (czyli wanie aspektw), ktre mona wydzieli do postaci niezalenych od siebie moduw i poczy wzajemnie tam, gdzie ich funkcje si krzyuj. Kod rdowy staje si przez to duo prostszy, bardziej elegancki, a jednoczenie zachowuje w peni swoj funkcjonalno.

W niniejszym rozdziale omwione zostan koncepcja programowania aspektowego oraz mechanizmy realizujce AOP w Spring Framework.

Osoby, ktre teoretyczne podstawy AOP maj ju opanowane, mog pomin lektur nastpnego podrozdziau i przej bezporednio do podrozdziau 4.3. 41

4.1. Wstp do aspektw

42

4.1. Wstp do aspektw


Aby nada naszym rozwaaniom konkretny ksztat przyjrzyjmy si prostemu przykadowi, swoistemu Hello World w wiecie aspektw. Zamy, e pewna aplikacja zawiera usug (metod), ktrej wywoania chcielibymy zalogowa w dzienniku zdarze. Interesowaby nas konkretnie czas wykonywania si pewnej metody. Stwrzmy usug wraz z interesujc nas metod:
Listing 4.1. Usuga, ktrej wywoania chcemy logowa
1 2 3 4 5 6 7 8 9 10 11 12 13 } } public c l a s s S e r v i c e implements I S e r v i c e { public void s e r v i c e ( ) { // meto da b i z n e s o w a package p r z y k l a d y . r o z d z i a l 4 ; } public i n t e r f a c e void s e r v i c e ( ) ; IService { package p r z y k l a d y . r o z d z i a l 4 ;

Metoda service() jest uywana w rnych miejscach projektu. Aby wykona nasze zadanie moemy doda do kodu aplikacji odpowiednie linijki:
Listing 4.2. Rozwizanie oczywiste
1 2 3 System . o u t . p r i n t l n ( Wchodze do metody s e r v i c e ( ) : service (); System . o u t . p r i n t l n ( Wychodze z metody s e r v i c e ( ) : + System . c u r r e n t T i m e M i l l i s ( ) ) ; + System . c u r r e n t T i m e M i l l i s ( ) ) ;

To dziaa, ma jednak jedn zasadnicz wad. Moe si zdarzy, e w bardzo krtkim czasie staniemy si posiadaczami kodu, w ktrym ilo linijek diagnostycznych bdzie wiksza ni kodu waciwego. Powinnimy wic poszuka lepszego rozwizania, ktre nie przyczyniaoby si do zaciemnienia kodu gwnego. Najprostszym rozwizaniem, jakie kademu zapewne przychodzi na myl jest umieszczenie linijki wypisujcej komunikat bezporednio w ciele metody service(). Jest to ju zdecydowanie lepsze rozwizanie. Kod wypisujcy komunikaty znajduje si w jednym miejscu i wszystko wydaje si by w porzdku. . . do czasu, gdy rozbudujemy nasz usug o kolejn metod biz-

4.1. Wstp do aspektw

43

nesow np. service2(), ktrej wywoania rwnie chcielibymy ujrze w dzienniku systemowym. Dodanie linijek System.out. . . do kadej nowej metody biznesowej nie rozwizuje globalnie problemu, przenosi go jedynie w inne miejsce. Trzeba poszuka wic jeszcze lepszego, denitywnego rozwizania.

4.1.1. Obiekty Proxy


JDK od wersji 1.3 oferuje moliwo tworzenia specjalnych obiektw, tzw. dynamicznych porednikw (ang. dynamic proxy). Nawet pobiena lektura API klasy java.lang.reflect.Proxy powinna wystarczy, aby uzna j za godn kandydatk do rozwizania naszego problemu. Dlaczego? Poniewa umoliwia wykonywanie metod nie bezporednio na obiektach, ale na porednikach, ktre z kolei deleguj (o ile tego chc) wywoanie do obiektu docelowego. Gdyby wic ustanowi obiekt poredniczcy dla naszej usugi to moe daoby si w obiekcie poredniczcym zaszy jakie sprytne logowanie wywoywania metod? Sprawdmy to!
Listing 4.3. Dynamiczny porednik
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 } public L o g g e r H a n d l e r ( O b j e c t this . target = target ; target ) { private Object target ; p r i v a t e c l a s s L o g g e r H a n d l e r implements I n v o c a t i o n H a n d l e r { } public void run ( ) { IService s v c = ( I S e r v i c e ) Proxy . n e w P r o x y I n s t a n c e ( { IService . class } , IService . class . getClassLoader () , new C l a s s [ ] svc . s e r v i c e ( ) ; svc . s e r v i c e 2 ( ) ; new L o g g e r H a n d l e r (new S e r v i c e ( ) ) ) ; } public s t a t i c void main ( S t r i n g [ ] new DynamicProxySample ( ) . run ( ) ; a r g s ) throws E x c e p t i o n { public c l a s s DynamicProxySample { import j a v a . l a n g . r e f l e c t . I n v o c a t i o n H a n d l e r ; import j a v a . l a n g . r e f l e c t . Method ; import j a v a . l a n g . r e f l e c t . Proxy ; package p r z y k l a d y . r o z d z i a l 4 ;

4.1. Wstp do aspektw

44

30 31 32 33 34 35 36 37 38 39 40 41 42 43 } } } p r i v a t e long t i m e ( ) { return System . c u r r e n t T i m e M i l l i s ( ) ; } public O b j e c t i n v o k e ( O b j e c t proxy , Method method , Object [ ] a r g s ) throws Throwable { args ) ; System . o u t . p r i n t l n ( + + method . getName ( ) + + t i m e ( ) ) ; O b j e c t r e t u r n V a l u e = method . i n v o k e ( t a r g e t , return r e t u r n V a l u e ; System . o u t . p r i n t l n ( + method . getName ( ) + + t i m e ( ) ) ;

Listing 4.3 pokazuje sposb, w jaki obiekty proxy umoliwiaj grupowanie pewnych problemw i kompleksowe ich rozwizywanie. W wierszach 14 17 tworzony jest obiekt porednika, ktry implementuje interfejs IService. Ostatni argument metody newProxyInstance() pozwala na przekazanie nowotworzonemu porednikowi kodu, ktry powinien zosta wykonany w momencie wywoania dowolnej metody ma obiekcie porednika. cile rzecz ujmujc jest to dowolna klasa implementujca interfejs InvocationHandler. W naszym przykadzie jest to klasa zdeniowana w wierszach 23 42. Jako argument konstruktora klasa LoggerHandler przyjmuje dowolny obiekt. Zatem przekazujc w konstruktorze obiekt klasy Service moemy w metodzie invoke(...) kontrolowa wywoania metod naszej usugi. Nasze nowe proxy bdzie delegowao wszystkie wywoania metod do usugi waciwej, a przy okazji moemy dopisa linijki diagnostyczne, o ktre nam chodzio. Dziki temu prostemu zabiegowi udekorowalimy nasz usug wzbogacajc nieco jej funkcjonalno. W ten sposb udao si cakiem sporo osign. Kod programu nie zawiera dodatkowych linijek, kod usugi pozosta nietknity, loguje wywoania metod niezalenie od ich iloci - po dodaniu nowych zachowa si dokadnie tak, jak tego oczekujemy. Jedyne, co musielimy zrobi to skorzysta z obiektu porednika i napisa fragment kodu realizujcy podan przez nas funkcjonalno. Idea dynamicznych porednikw to podstawa, na ktrej zbudowany zosta framework AOP w Spring Framework. Zanim jednak przejdziemy do omwienia

4.2. Aspekty pod lup

45

szczegw tej czci Spring Framework warto powici jeszcze kilka chwil samym aspektom.

4.2. Aspekty pod lup


4.2.1. Koncepcja AOP
Przeanalizujmy, co skonio nas do uycia obiektu proxy? Przede wszystkim zidentykowalimy pewne powtarzajce si zadanie. Zauwaylimy, e zadanie to wymaga cigego stosowania podobnego lub wrcz identycznego kodu. Na dodatek kod ten jest funkcjonalnie niezaleny od logiki aplikacji waciwej (nasza przykadowa aplikacja bdzie bez niego dziaa poprawnie, cho nie bdzie wypisywaa komunikatw).

Aspekty W terminologii AOP powiedzielibymy, e wyodrbnilimy pewien aspekt, ktry by moe wymaga szczeglnego potraktowania. Aspekt jest wic wydzielon funkcjonalnie czci programu, pewnym moduem, ktry moemy bezkolizyjnie i bezinwazyjnie poczy z innymi moduami (aspektami). Realizuje on okrelone zadanie i koncentruje si tylko na problemie (ang. concern), ktrego cile dotyczy (np. trzymajc si naszego przykadu bdzie to np. logowanie wywoywania metod). Wszdzie tam, gdzie mamy do czynienia z zazbianiem, czy przecinaniem si pewnych zada moemy zastosowa aspekty w miejsce tradycyjnego tworzenia hierarii klas i zawiych powiza midzy nimi. Problem przecinania si zada (ang. cross-cutting concerns) dotyczy niemal kadej aplikacji. Np. aplikacja musi by zarwno wydajna, jak i bezpieczna (wydajno i bezpieczestwo mona potraktowa jako przykady aspektw). Zadania te mona sobie wyobrazi jako pewne paszczyzny, ktre dopiero w aplikacji znajduj pewien punkt przecicia - spotykaj si, by wsplnie realizowa kompleksowe zadanie. Aspekty i AOP sprawiaj, e

4.2. Aspekty pod lup

46

realizacja takich zada jest prosta, znacznie prostsza ni w tradycyjnym obiektowym podejciu, opartym na hierarchii klas. Aspekty umoliwiaj lepsz enkapsulacj (usuga biznesowa nie musi wiedzie, czy logowane s wywoania jej metod, a modu logujcy nie musi wiedzie, co waciwie loguje) oraz zwikszaj w znacznym stopniu ponowne wykorzystanie raz napisanego kodu (nasz aspekt, jako samodzielnie funkcjonujcy modu, moemy zastosowa z dowoln inn usug biznesow).

Instrukcje W jaki sposb dodalimy nowy aspekt do kodu naszej usugi? Uylimy obiektu proxy, ktry otoczy wywoanie kadej metody biznesowej usugi pewnym dodatkowym kodem. w kod nazwany jest w wiecie aspektw instrukcj (ang. advice). W dalszej czci tego rozdziau przekonamy si, e istnieje kilka typw instrukcji, ktrych moemy uywa w zalenoci od potrzeb. Dziki instrukcjom moemy wpywa na przebieg wykonywania programu poprzez wzbogacenie kodu, podmienianie go, albo odpowiednie reagowanie, w przypadku pojawienia si wyjtku.

Punkty zcze Punkt zczenia (ang. join point) to dowolne miejsce w kodzie programu gwnego (w naszym przykadzie jest to kod usugi), w ktrzym styka si on z aspektem. Punktem zczenia w naszej aplikacji jest wywoanie metody biznesowej. W tym miejscu aplikacja powinna oprcz wasnego kodu wykona rwnie kod instrukcji (jednej lub wicej). Wywoanie metody to pewnie najprostszy, ale oczywicie nie jedyny moliwy punkt zczenia. Inne przykady to m.in.:

wywoanie konstruktora pewnej klasy, dostp do pola,

4.2. Aspekty pod lup wykonanie jakiego szczeglnego kawaka kodu, wystpienie wyjtku, etc.

47

Punkt przecicia Ostatnim wanym pojciem z zakresu AOP jest punkt przecicia (ang. pointcut), ktry jest niczym innym, jak tylko zbiorem punktw zcze. Punkt przecicia okrela, w ktrych miejscach aspekt spotyka si z kodem gwnym. W przypadku naszej przykadowej usugi punktem przecicia s wszystkie jej metody. Rne narzdzia AOP stosuj rne notacje umoliwiajce deniowanie punktw przeci. Jednym z powszechniej stosowanych sposobw jest uycie wyrae regularnych celem wskazania metod nalecych do danego punktu przecicia. Np. wyraenie set* oznacza moe wszystkie metody ustawiajce (settery).

4.2.2. Sposoby implementacji AOP


W jaki sposb mona zaimplementowa AOP? Istniej przynajmniej dwie powszechnie stosowane metody implementacji paradygmatu AOP. Przyjrzyjmy si dokadniej, na czym one polegaj.

Obiekt proxy Podstawowym i najbardziej naturalnym narzdziem, ktre ju poznalimy, jest obiekt proxy. Niezaprzeczaln zalet tego rozwizania jest jego prostota i wsparcie ze strony samego jzyka Java. Podejcie to nie jest jednak pozbawione wad, z ktrych najwaniejsz jest brak moliwoci tworzenia obiektw proxy dla konkretnych klas. Jzyk Java przewiduje tylko i wycznie tworzenie obiektw proxy dla interfejsw.

4.2. Aspekty pod lup

48

Drug ciemn stron stosowania obiektw dynamicznych porednikw jest ich nisza ni czystych klas wydajno. Zwizany z utworzeniem i dziaaniem obiektu proxy dodatkowy narzut czasowy, moe, przy bardzo czstych wywoaniach metod, nie by obojtny dla oglnej wydajnoci aplikacji1 .

Generowanie byte-codeu Nie zawsze stosowanie prostych obiektw proxy jest wystarczajce. Nietrudno wyobrazi sobie sytuacj, gdy usuga nie implementuje adnego interfejsu i nie mamy jej kodu rdowego (np. jest to zakupiona komercyjna, zamknita biblioteka). Czy mona w takiej sytuacji zastosowa AOP? Mona, cho trzeba uciec si do nieco bardziej wyranowanej metody, a mianowicie sztuczki okrelanej mianem generowania byte-codeu. Korzystajc z pomocy takich bibliotek jak np. CGLIB (http://cglib.sf.net) mona w locie wygenerowa kod binarny klasy, ktra oprcz wasnej funkcjonalnoci zostanie wzbogacona o funkcjonalno pochodzc z kodu instrukcji. Ten sposb nie tylko eliminuje problem wydajnoci, ale rwnie pozwala w duym stopniu rozszerzy moliwoci aspektw. Wreszcie moliwe staje si: stworzenie porednika dla konkretnej klasy, a nie tylko dla interfejsu, dodanie interfejsw do klas, ktre pierwotnie ich nie implementuj, deniowane punktw zcze np. wewntrz metod.

Wariacje na temat AOP Wyej wymienione narzdzia realizacji AOP wystpuj w rnych wariantach. Niektre projekty realizuj AOP na poziomie instancji, inne na poziomie caej klasy. Ten drugi przypadek wymaga zastosowania dedykowanej
1

cho trzeba przyzna, e z kadym nowym wydaniem JVM wydajno tego rozwiza-

nia ronie

4.2. Aspekty pod lup

49

adowarki klas (ang. classloader ), ktra w miejsce zwykej instancji klasy utworzy instancj wzbogacon o kod instrukcji. Innym przykadem moe by wygenerowanie wzbogaconego kodu Java, jeszcze przed kompilacj programu, cho od tego rozwizania konsekwentnie si odchodzi ze wzgldu nie niewygod stosowania i moliwo osignicia tych samych efektw przy znacznie mniejszych nakadach pracy.

4.2.3. Zastosowania AOP


Opanowawszy teoretyczne podstawy programowania aspektowego (szczegy poznamy za chwil) zastanwmy si do czego mona wykorzysta t koncepcj w praktyce? Jakie proty moe przynie stosowanie AOP typowej aplikacji? Do czego AOP jest przewanie stosowany?

Diagnozowanie i monitorowanie Mielimy ju okazj pozna jedno zastosowanie aspektw, czyli dodawanie do kodu linijek diagnostycznych informujcych o stanie aplikacji. W ten sposb mona monitorowa wydajno i stan programu. Przewaga aspektw nad specjalistycznymi bibliotekami do logowania zdarze polega na tym, e kod bazowy aplikacji nie zawiera dodatkowych, zaciemniajcych algorytm linii. Logowanie zdarze realizowane jest w sposb przezroczysty. Co wicej, aspekt diagnostyczny mona np. wyczy w produkcyjnej instalacji aplikacji (jeli powodowaby zbyt due obcienie), czy te zamieni go na, bardziej w takiej sytuacji przydatny, aspekt monitorujcy.

Kontrola dostpu Wyobramy sobie sytuacj, w ktrej dostp do wybranych czci aplikacji wymaga specjalnych uprawnie, np. uytkownik powinien by zalogowany i posiada odpowiedni rol. Jak to osign? W tradycyjnym podejciu naleaoby przed wejciem lub tu po wejciu do chronionych metod sprawdzi czy spenione s warunki bezpieczestwa.

4.2. Aspekty pod lup

50

Kada chroniona metoda posiadaaby podobny lub identyczny kod gwarantujcy spenienie wymogw bezpieczestwa. Dziki aspektom moliwe jest wydzielenie takiego kodu wartownika do swoistej czarnej skrzynki, a poprzez odpowiednie zdeniowanie punktw przeci proste staje si rozpicie parasola ochronnego nad wszystkimi chronionymi fragmentami kodu bazowego. Co wane, dzieje si to w sposb cakowicie transparentny dla aplikacji.

Transakcje Kolejne, bodaj najpowszechniejsze, zastosowanie AOP to wydzielenie do niezalenego moduu caego kodu zwizanego z zarzdzaniem transakcjami. W przypadku transakcji bazodanowych oznacza to, e kod bazowy aplikacji wykonuje tylko i wycznie zapytania SQL zwizane z operacjami na rekordach (bezporednio lub z wykorzystaniem bibliotek O/R), nie przejmujc si szczeglnie wspbienoci. Transakcyjno zapewniana jest przez odpowiednio skonstruowany aspekt. Punktami zcze bd w takim przypadku wszystkie metody load(...), save(...), delete(...), etc., ktre dokonuj trwaych modykacji danych. Metody te stan si dziki aspektowi duo czytelniejsze, nie bd zawieray niekoczcych si blokw try {BEGIN ... COMMIT} catch {ROLLBACK}. Bd tylko staray si wykona swoje podstawowe zadanie, a zapewnienie wycznego dostpu do rda danych i stosown reakcj na ewentualne wyjtki zapewni aspekt.

Pami podrczna Aspektw mona rwnie uy do dodania do aplikacji pamici podrcznej (ang. cache), przyspieszajcej jej dziaanie. Aplikujc odpowiedni aspekt w kodzie bazowym mona przechwyci wywoanie niektrych czasochonnych metod, sprawdzi argumenty wejciowe metody, a nastpnie poszuka w pamici podrcznej, czy dla tych agrumentw nie zostaa ju wczeniej wyliczona i zapamitana warto wynikowa.

4.2. Aspekty pod lup

51

Jeli tak, to mona zwrci t warto bezporednio, bez wykonywania czasochonnego algorytmu. Znowu moe dzia si to w sposb niezauwaalny dla aplikacji.

Inne zastosowania

Zastosowa aspektw moe by oczywicie znacznie wicej. Przytoczone przykady su jedynie do lepszego zobrazowania caej idei i nadania jej realnego ksztatu. Dziki aspektom moliwe staje si pisanie przejrzystych, eleganckich i modularnych aplikacji, dlatego warto rozway to podejcie przed napisaniem wikszego fragmentu kodu - by moe AOP stanowi bdzie najprostsze i optymalne rozwizanie. Nawet jeli nie wiemy dokadnie, w jakim kierunku tworzona przez nas aplikacja bdzie w przyszoci ewoluowa, aspekty mog okaza si jedyn drog do szybkiego dodawania nowej funkcjonalnoci, bez potrzeby wprowadzania rewolucyjnych zmian w kodzie bazowym.

4.2.4. Frameworki AOP


Framework AOP to zbir narzdzi, ktrych zadaniem jest umoliwienie stosowania paradygmatu programowania aspektowego w sposb moliwie prosty, efektywny, powtarzalny i niewidoczny dla bazowego kodu aplikacji. W praktyce frameworki AOP to specjalne biblioteki, ktre obudowuj podstawowe narzdzia realizacji aspektw (proxy oraz generowanie bytecodeu) w dodatkowe, uatwiajce ich uywanie funkcje, takie jak np. elastyczna konguracja (zaawansowane moliwoci deniowania punktw przeci np. w czytelnych plikach XML), czy repozytoria gotowych do uycia, czsto powtarzajcych si w aplikacjach instrukcji.

4.2. Aspekty pod lup AspectJ

52

adna ksika, w ktrej poruszana jest tematyka programowania aspektowego, nie moe pomin znaczenia pierwszego i najwaniejszego projektu AOP, jakim zapewne jest AspectJ2 . AspectJ jest najpopularniejszym frameworkiem AOP, stworzonym m.in. przez samego autora koncepcji AOP Gregora Kiczalesa. Jest to najprawdopodobniej najbardziej zaawansowany projekt tego typu, oferujcy najszersze spektrum moliwoci. AspectJ rozszerza jzyk Java o dodatkowe sowa kluczowe i skadni umoliwiajc deniowanie aspektw. Kod napisany w AspectJ jest integrowany z byte-codem aplikacji bazowej w procesie okrelanym mianem weaving. Weaving polega na zlokalizowaniu na podstawie denicji zawartych w kodzie AspectJ punktw przeci i odpowiednim zmodykowaniu bytecodeu aplikacji bazowej. W wyniku tego procesu generowany jest nowy byte-code, wzbogacony o kod pochodzcy z instrukcji. Jeli weaving zostanie wykonany tu po skompilowaniu klas aplikacji bazowej i przed uruchomieniem JVM to mwimy o kompilacji statycznej. Drugim sposobem jest manipulowanie byte-codem ju w czase pracy aplikacji, co okrelane jest mianem load-time weaving. Stworzenie rozszerzenia jzyka Java i dodatkowy krok kompilacji, jakim jest weaving, mog by postrzegane jako najwiksza wada AspectJ. Autorzy projektu zadbali jednak o to, aby tworzenie aspektw nie byo dla programisty zbyt uciliwe. Dostpna jest wtyczka do rodowiska Eclipse AspectJ Development Tools3 (AJDT), dziki ktrej korzystanie z AspectJ staje si prostsze. Osoby szerzej zainteresowane zagadnieniem AOP powinny koniecznie zapozna si z tym projektem.

2 3

http://eclipse.org/aspectj http://www.eclipse.org/ajdt/

4.2. Aspekty pod lup Inne projekty AOP

53

Podobnie jak wiele innych dziedzin AOP rwnie przeszed przez faz bujnego rozkwitu. Nie dziao si to moe na a tak wielk skal, jak mielimy (i mamy nadal!) okazj podziwia w przypadku frameworkw do tworzenia aplikacji internetowych, ale i tak wiat Javy doczeka si co najmniej kilkunastu projektw dedykowanych AOP. Spord bardziej znanych warto wymieni:

AspectWerkz - http://aspectwerkz.codehaus.org/, Nanning - http://nanning.codehaus.org/, JBossAOP - http://www.jboss.org/products/aop, Spring Framework AOP

Wszystkie wyej wymienione rozwizania stosuj odmienne podejcie ni AspectJ. Nie rozszerzaj one jzyka Java, ani te nie tworz wasnego. Operuj wycznie na czystych obiektach POJO, kod wskazwek to zwyke klasy, a konguracja AOP przewanie realizowana jest w pliku XML. S to wic rozwizania atwiejsze w uyciu, gdy nie wymagaj adnych dodatkowych narzdzi. Ostatnie dwa projekty (JBossAOP oraz Spring Framework AOP) wydaj si zdobywa coraz wiksz popularno, co po czci wynika z tego, e zwizane s cile z bardzo popularnymi na rynku produktami. Oczywicie nie jest to gwny powd ich szerokiego stosowania - w rzeczywistoci s to potne narzdzia, ktre, jak si przekonamy podczas omawiania Spring Framework AOP, umoliwiaj osignicie zdumiewajcych rezultatw przy jednoczesnym zachowaniu przejrzystoci kodu. Po tym, nieco dugim, wstpnie moemy przystpi do zagbienia si w AOP w Spring Framework, ktry, zaraz po beanach i kontenerze IoC, jest trzecim najwaniejszym skadnikiem tej platformy.

4.3. AOP w Spring Framework

54

4.3. AOP w Spring Framework


Framework AOP w Spring Framework to rozwizanie czysto Javowe. Nie wymagana jest wic specyczna skadnia do tworzenia aspektw, jak to ma miejsce w AspectJ, nie ma te oddzielnego procesu weavingu. Oczywicie taka decyzja twrcw Spring Framework pociga za sob pewne konsekwencje, z ktrych najistotniejsz jest ta, e framework ten nie umoliwia implementacji wszystkich koncepcji, ktre mog by z powodzeniem zrealizowane przy uyciu AspectJ. Bya to jednak decyzja wiadoma. Sami twrcy Spring Framework okrelaj swj AOP jako: narzdzie, ktre w poczeniu z kontenerem IoC ma w prosty sposb rozwizywa typowe problemy aplikacji klasy enterprise, narzdzie umoliwiajce korzystanie w programie z rnych usug enterprise (np. EJB, JTA) w sposb deklaratywny. To pragmatyczne podejcie dao w efekcie bardzo proste i elastyczne w uyciu narzdzie, ktre w poczeniu z gotowymi klasami rozwizujcymi typowe problemy aplikacji staje si wrcz niezastpione. Uytkownikowi, ktry potrzebuje tylko podstawowych funkcji AOP, wystarczy kilkanacie minut, eby mc samodzielnie deniowa aspekty w Spring Framework. Zobaczmy jak wygldaaby nasza przykadowa usuga, zrealizowana z uyciem Spring IoC i Spring AOP.

4.3.1. org.springframework.aop.framework.ProxyFactoryBean
ProxyFactoryBean to specjalny bean, ktry potra utworzy instancj dynamicznego porednika dla dowolnego obiektu. Jest to wic podstawowe narzdzie realizacji AOP w Spring Framework.

Podsumowanie
Czas na podsumowanie

55

56

Listings
3.1. Pierwszy bean HelloWorld . . . . . . . . . . . . . . . . . . . 3.2. Minimalny plik konguracyjny w wersji XML . . . . . . . . . 3.3. Minimalny plik konguracyjny w wersji *.properties . . . . . 3.4. Przykad wykorzystania beanu HelloWorld . . . . . . . . . . . 3.5. Bardziej szczegowy plik konguracyjny . . . . . . . . . . . . 3.6. Klasa bez konstruktora domylnego . . . . . . . . . . . . . . . 3.7. Konguracja waciwoci beanw . . . . . . . . . . . . . . . . 3.8. Deniowanie kolekcji . . . . . . . . . . . . . . . . . . . . . . . 3.9. Metody zgodne ze specykacj JavaBean . . . . . . . . . . . . 3.10. Zagniedony bean . . . . . . . . . . . . . . . . . . . . . . . . 3.11. Interfejs InitializingBean . . . . . . . . . . . . . . . . . . . . . 3.12. Interfejs DisposableBean . . . . . . . . . . . . . . . . . . . . . 3.13. Deklaratywne deniowanie cyklu ycia . . . . . . . . . . . . . 3.14. Przykad konguracji beanu z polem typu java.util.Date . . . 3.15. Metoda ustawiajca pole date . . . . . . . . . . . . . . . . . . 3.16. Rejestrowanie wasnych edytorw waciwoci . . . . . . . . . 3.17. Klasa bez konstruktora domylnego . . . . . . . . . . . . . . . 3.18. Konguracja kontruktora . . . . . . . . . . . . . . . . . . . . 3.19. Interfejs org.springframework.beans.factory.FactoryBean . . . 57 17 17 17 18 18 20 21 21 22 22 24 24 25 26 26 26 27 27 28

Listings 3.20. Fabryki beanw . . . . . . . . . . . . . . . . . . . . . . . . . . 3.21. Przykadowe beany - NameProvider . . . . . . . . . . . . . . 3.22. Przykadowe beany - NameWriter . . . . . . . . . . . . . . . . 3.23. Wstrzykiwanie zalenoci przy pomocy setterw . . . . . . . . 3.24. Wstrzykiwanie zalenoci przy pomocy konstruktorw . . . . 3.25. Dopasowywanie zalenoci wg nazwy . . . . . . . . . . . . . . 3.26. Dopasowywanie zalenoci wg typu . . . . . . . . . . . . . . . 3.27. Dopasowywanie zalenoci wg konstruktorw . . . . . . . . . 3.28. Domylna polityka autodopasowania . . . . . . . . . . . . . . 4.1. Usuga, ktrej wywoania chcemy logowa . . . . . . . . . . . 4.2. Rozwizanie oczywiste . . . . . . . . . . . . . . . . . . . . . . 4.3. Dynamiczny porednik . . . . . . . . . . . . . . . . . . . . . .

58 28 31 31 32 32 35 36 37 38 42 42 43

Spis rysunkw

59

Spis rysunkw

60

Spis tablic

61

You might also like