Darmowy fragment publikacji:
Tytuł oryginału: Spring in Action, 3rd edition
Tłumaczenie: Jacek Kowolik (wstęp, rozdz. 1 – 4);
Krzysztof Wołowski (rozdz. 5 – 14)
Projekt okładki: Anna Mitka
Materiały graficzne na okładce zostały wykorzystane za zgodą Shutterstock Images LLC.
ISBN: 978-83-246-4888-7
Original edition copyright © 2011 by Manning Publications Co.
All rights reserved.
Polish edition copyright © 2013 by HELION SA.
All rights reserved.
All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means,
electronic or mechanical, including photocopying, recording or by any information storage retrieval system,
without permission from the Publisher.
Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej
publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną,
fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje
naruszenie praw autorskich niniejszej publikacji.
Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich
właścicieli.
Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były
kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane
z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie
ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji
zawartych w książce.
Wydawnictwo HELION
ul. Kościuszki 1c, 44-100 GLIWICE
tel. 32 231 22 19, 32 230 98 63
e-mail: helion@helion.pl
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie/sprwa3
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
Pliki z przykładami omawianymi w książce można znaleźć pod adresem:
ftp://ftp.helion.pl/przyklady/sprwa3.zip
Printed in Poland.
• Kup książkę
• Poleć książkę
• Oceń książkę
• Księgarnia internetowa
• Lubię to! » Nasza społeczność
Spis treĂci
Przedmowa ............................................................................................................................................... 11
PodziÚkowania .......................................................................................................................................... 13
O ksiÈĝce ................................................................................................................................................... 15
CZ}¥m 1. PODSTAWY FRAMEWORKA SPRING
Rozdziaï 1. Zrywamy siÚ do dziaïania
Rozdziaï 2. Tworzymy powiÈzania miÚdzy komponentami
1.2.1.
1.2.2.
1.4.1.
1.4.2.
1.4.3.
21
1.1. Upraszczamy programowanie w Javie ....................................................................................... 22
1.1.1. Uwalniamy moc zawartÈ w POJO ................................................................................ 23
1.1.2. Wstrzykujemy zaleĝnoĂci .............................................................................................. 25
1.1.3.
Stosujemy aspekty ......................................................................................................... 29
1.1.4. Ograniczamy stosowanie kodu szablonowego dziÚki wzorcom .................................. 33
1.2. Kontener dla naszych komponentów ......................................................................................... 36
Pracujemy z kontekstem aplikacji ................................................................................ 37
Cykl ĝycia komponentu ................................................................................................. 37
1.3. Podziwiamy krajobraz Springa ................................................................................................... 39
1.3.1. Moduïy Springa ............................................................................................................. 39
1.3.2.
Rodzina projektów wokóï Springa ............................................................................... 42
1.4. Co nowego w Springu .................................................................................................................. 46
Co nowego w Springu 2.5? ........................................................................................... 46
Co nowego w Springu 3.0? ........................................................................................... 47
Co nowego w rodzinie projektów otaczajÈcych Springa? ........................................... 47
1.5. Podsumowanie .............................................................................................................................. 48
49
2.1. Deklarujemy komponenty ........................................................................................................... 50
2.1.1.
Tworzymy konfiguracjÚ Springa .................................................................................. 51
2.1.2. Deklarujemy prosty komponent ................................................................................... 51
2.1.3. Wstrzykujemy przez konstruktory ............................................................................... 53
2.1.4. Ustalamy zakres komponentów .................................................................................... 58
2.1.5.
Inicjalizujemy i likwidujemy komponenty .................................................................. 59
2.2. Wstrzykujemy wartoĂci do wïaĂciwoĂci komponentu .............................................................. 61
2.2.1. Wstrzykujemy proste wartoĂci ..................................................................................... 62
2.2.2. Wstrzykujemy referencje do innych beanów .............................................................. 63
2.2.3. WiÈĝemy wïaĂciwoĂci w przestrzeni nazw p Springa ................................................. 66
2.2.4. WiÈĝemy kolekcje ......................................................................................................... 67
2.2.5. WiÈĝemy nic (null) ........................................................................................................ 72
2.3. WiÈĝemy za pomocÈ wyraĝeñ ..................................................................................................... 72
2.3.1.
Podstawy wyraĝeñ w SpEL .......................................................................................... 73
2.3.2. Wykonujemy operacje na wartoĂciach w jÚzyku SpEL .............................................. 76
2.3.3.
Przesiewamy kolekcje za pomocÈ SpEL ...................................................................... 80
2.4. Podsumowanie .............................................................................................................................. 83
6
Spis treĂci
3.2.1.
3.2.2.
3.2.3.
Rozdziaï 4. Aspektowy Spring
Rozdziaï 3. Ograniczamy uĝycie jÚzyka XML w konfiguracji Springa
85
3.1. Automatycznie wiÈĝemy wïaĂciwoĂci komponentów ................................................................ 86
3.1.1.
Cztery rodzaje automatycznego wiÈzania .................................................................... 86
3.1.2. DomyĂlny styl automatycznego wiÈzania .................................................................... 90
3.1.3. Mieszamy wiÈzanie automatyczne i jawne .................................................................. 91
3.2. WiÈĝemy za pomocÈ adnotacji ................................................................................................... 92
Korzystamy z adnotacji @Autowired ........................................................................... 92
Stosujemy automatyczne wiÈzanie zgodne ze standardami,
korzystajÈc z adnotacji @Inject .................................................................................... 97
Posïugujemy siÚ wyraĝeniami podczas wstrzykiwania przez adnotacje .................... 99
3.3. Automatyczne wykrywanie komponentów .............................................................................. 100
3.3.1. Oznaczamy komponenty adnotacjami dla automatycznego wykrywania ................. 100
3.3.2. Dodajemy filtry do skanera komponentów ................................................................ 102
3.4. Uĝywamy w Springu konfiguracji opartej na Javie ................................................................ 103
3.4.1.
Przygotowujemy siÚ do stosowania konfiguracji opartej na Javie ............................ 103
3.4.2. Definiujemy klasÚ konfiguracyjnÈ .............................................................................. 104
3.4.3. Deklarujemy prosty komponent ................................................................................. 104
3.4.4. Wstrzykujemy w Springu za pomocÈ konfiguracji opartej na Javie ......................... 105
3.5. Podsumowanie ............................................................................................................................ 106
107
4.1. Czym jest programowanie aspektowe ...................................................................................... 108
4.1.1. Definiujemy terminologiÚ dotyczÈcÈ AOP ................................................................ 109
4.1.2. Obsïuga programowania aspektowego w Springu .................................................... 112
4.2. Wybieramy punkty zïÈczenia za pomocÈ punktów przeciÚcia .............................................. 115
Piszemy definicje punktów przeciÚcia ....................................................................... 116
Korzystamy z desygnatora bean() w Springu ............................................................. 117
4.3. Deklarujemy aspekty w jÚzyku XML ....................................................................................... 117
4.3.1. Deklarujemy porady before i after ............................................................................. 119
4.3.2. Deklarujemy poradÚ around ....................................................................................... 121
4.3.3.
Przekazujemy parametry do porady ........................................................................... 123
4.3.4. Wprowadzamy nowÈ funkcjonalnoĂÊ przez aspekty ................................................. 125
4.4. Uĝywamy adnotacji dla aspektów ............................................................................................. 127
Tworzymy poradÚ around za pomocÈ adnotacji ........................................................ 129
Przekazujemy argumenty do porad konfigurowanych przez adnotacje ................... 130
Tworzymy wprowadzenie za pomocÈ adnotacji ........................................................ 131
4.5. Wstrzykujemy aspekty z AspectJ .............................................................................................. 132
4.6. Podsumowanie ............................................................................................................................ 135
4.4.1.
4.4.2.
4.4.3.
4.2.1.
4.2.2.
CZ}¥m 2. PODSTAWY APLIKACJI SPRINGA
Rozdziaï 5. Korzystanie z bazy danych
139
5.1. Filozofia dostÚpu do danych Springa ....................................................................................... 140
5.1.1. Hierarchia wyjÈtków zwiÈzanych z dostÚpem do danych w Springu ...................... 141
5.1.2.
Szablony dostÚpu do danych ...................................................................................... 143
Klasy bazowe DAO ..................................................................................................... 145
5.1.3.
5.2. Konfiguracja ěródïa danych ...................................................................................................... 147
½ródïa danych JNDI ................................................................................................... 147
½ródïa danych z pulÈ ................................................................................................... 147
½ródïo danych oparte na sterowniku JDBC .............................................................. 149
5.2.1.
5.2.2.
5.2.3.
Spis treĂci
7
5.4.
5.5.1.
5.5.2.
6.1.1.
6.1.2.
Rozdziaï 6. ZarzÈdzanie transakcjami
6.2.1.
6.2.2.
6.2.3.
6.2.4.
5.3. Uĝywanie JDBC w Springu ....................................................................................................... 149
Kod JDBC a obsïuga wyjÈtków .................................................................................. 150
5.3.1.
5.3.2.
Praca z szablonami JDBC ........................................................................................... 153
Integracja Hibernate ze Springiem ......................................................................................... 158
5.4.1.
PrzeglÈd Hibernate ..................................................................................................... 159
5.4.2. Deklarowanie fabryki sesji Hibernate ....................................................................... 160
5.4.3. Hibernate bez Springa ................................................................................................ 162
5.5. Spring i Java Persistence API ................................................................................................... 163
Konfiguracja fabryki menedĝerów encji .................................................................... 164
Klasa DAO na bazie JPA ............................................................................................. 168
5.6. Podsumowanie ............................................................................................................................ 169
171
6.1. Zrozumienie transakcji .............................................................................................................. 172
Cztery sïowa kluczowe do zrozumienia transakcji .................................................... 173
Zrozumienie obsïugi zarzÈdzania transakcjami w Springu ....................................... 174
6.2. Wybór menedĝera transakcji .................................................................................................... 175
Transakcje JDBC ........................................................................................................ 175
Transakcje Hibernate .................................................................................................. 176
Transakcje Java Persistence API ................................................................................ 177
Transakcje Java Transaction API ................................................................................ 178
6.3. Programowanie transakcji w Springu ...................................................................................... 178
6.4. Deklarowanie transakcji ........................................................................................................... 180
6.4.1. Definiowanie atrybutów transakcji ............................................................................ 180
6.4.2. Deklarowanie transakcji w XML ................................................................................ 184
6.4.3. Definiowanie transakcji sterowanych adnotacjami ................................................... 186
6.5. Podsumowanie ............................................................................................................................ 187
189
7.1. Wprowadzenie do Spring MVC ............................................................................................... 190
Cykl ĝycia ĝÈdania w Spring MVC ............................................................................. 190
Konfiguracja Spring MVC .......................................................................................... 192
7.2. Budowa podstawowego kontrolera .......................................................................................... 193
7.2.1.
Konfiguracja Spring MVC sterowanego adnotacjami ............................................... 194
7.2.2. Definiowanie kontrolera strony gïównej ................................................................... 195
7.2.3.
Produkowanie widoków .............................................................................................. 198
7.2.4. Definiowanie widoku strony gïównej ........................................................................ 202
7.2.5. Dopracowanie kontekstu aplikacji Springa ............................................................... 203
7.3. Kontroler obsïugujÈcy dane wprowadzane przez uĝytkownika ............................................ 205
7.3.1.
Budowa kontrolera przetwarzajÈcego dane wprowadzane przez uĝytkownika ....... 205
7.3.2. WyĂwietlenie widoku .................................................................................................. 207
7.4. Przetwarzanie formularzy ......................................................................................................... 208
7.4.1. WyĂwietlenie formularza rejestracyjnego .................................................................. 209
7.4.2.
Przetwarzanie formularza ........................................................................................... 211
7.4.3. Walidacja przesyïanych danych ................................................................................. 213
7.5. Obsïuga plików wysyïanych na serwer .................................................................................... 217
7.5.1. Dodanie pola selektora plików do formularza ........................................................... 217
7.5.2. Odbieranie plików wysyïanych na serwer ................................................................. 218
7.5.3.
Konfiguracja Springa do przesyïania plików na serwer ............................................ 221
7.6. Podsumowanie ............................................................................................................................ 221
7.1.1.
7.1.2.
Rozdziaï 7. Budowanie aplikacji sieciowych za pomocÈ Spring MVC
8
Spis treĂci
Rozdziaï 8. Praca ze Spring Web Flow
8.1.
Rozdziaï 9. Zabezpieczanie Springa
223
Instalacja Spring Web Flow ..................................................................................................... 224
8.1.1.
Konfiguracja Spring Web Flow .................................................................................. 224
8.2. Skïadowe przepïywu .................................................................................................................. 227
Stany ............................................................................................................................ 227
8.2.1.
8.2.2.
PrzejĂcia ....................................................................................................................... 230
8.2.3. Dane przepïywu .......................................................................................................... 231
8.3. Èczymy wszystko w caïoĂÊ: zamówienie pizzy ...................................................................... 233
8.3.1. Definiowanie bazowego przepïywu ........................................................................... 233
Zbieranie informacji o kliencie ................................................................................... 237
8.3.2.
Budowa zamówienia ................................................................................................... 242
8.3.3.
8.3.4.
Przyjmowanie pïatnoĂci .............................................................................................. 245
8.4. Zabezpieczanie przepïywu ........................................................................................................ 247
8.5. Podsumowanie ............................................................................................................................ 247
249
9.1. Wprowadzenie do Spring Security .......................................................................................... 250
Rozpoczynamy pracÚ ze Spring Security ................................................................... 250
Konfiguracyjna przestrzeñ nazw Spring Security ..................................................... 251
9.2. Zabezpieczanie ĝÈdañ sieciowych ............................................................................................ 252
9.2.1.
PoĂredniczenie w dostÚpie do filtrów serwletów ...................................................... 252
9.2.2. Minimalna konfiguracja bezpieczeñstwa sieciowego ................................................ 253
9.2.3.
Przechwytywanie ĝÈdañ .............................................................................................. 257
9.3. Zabezpieczanie elementów na poziomie widoku .................................................................... 259
9.3.1. DostÚp do informacji uwierzytelniajÈcych ................................................................ 260
9.3.2. WyĂwietlanie z uprawnieniami .................................................................................. 261
9.4. Uwierzytelnianie uĝytkowników ............................................................................................... 263
9.4.1.
Konfiguracja repozytorium w pamiÚci operacyjnej .................................................. 263
9.4.2. Uwierzytelnianie za pomocÈ bazy danych ................................................................. 264
9.4.3. Uwierzytelnianie za pomocÈ LDAP ........................................................................... 266
9.4.4. WïÈczenie funkcji „pamiÚtaj mnie” ............................................................................ 269
9.5. Zabezpieczanie metod ............................................................................................................... 270
Zabezpieczanie metod z adnotacjÈ @Secured .......................................................... 270
9.5.1.
Adnotacja @RolesAllowed ze specyfikacji JSR-250 ................................................. 271
9.5.2.
9.5.3.
Zabezpieczenia przed wykonaniem metody ze SpEL i po jej wykonaniu .............. 271
9.5.4. Deklaracja przeciÚÊ bezpieczeñstwa na poziomie metody ....................................... 276
9.6. Podsumowanie ............................................................................................................................ 276
9.1.1.
9.1.2.
CZ}¥m 3. INTEGRACJA W SPRINGU
Rozdziaï 10. Praca ze zdalnymi usïugami
279
10.1. Zdalny dostÚp w Springu ........................................................................................................... 280
10.2. Praca z RMI ................................................................................................................................ 282
10.2.1. Eksportowanie usïugi RMI ........................................................................................ 283
10.2.2. DowiÈzanie usïugi RMI .............................................................................................. 285
10.3. UdostÚpnianie zdalnych usïug za pomocÈ Hessian i Burlap ................................................. 287
10.3.1. UdostÚpnianie funkcjonalnoĂci komponentu za pomocÈ Hessian/Burlap ............... 288
10.3.2. DostÚp do usïug Hessian/Burlap ................................................................................ 290
Rozdziaï 11. Spring i model REST
Rozdziaï 12. Obsïuga komunikatów w Springu
Spis treĂci
9
10.4. Obiekt HttpInvoker ................................................................................................................... 292
10.4.1. UdostÚpnianie komponentów jako usïug HTTP ....................................................... 292
10.4.2. DostÚp do usïug przez HTTP ..................................................................................... 293
10.5. Publikacja i konsumpcja usïug sieciowych .............................................................................. 294
10.5.1. Tworzenie punktów koñcowych JAX-WS w Springu ............................................... 295
10.5.2. PoĂrednik usïug JAX-WS po stronie klienta .............................................................. 299
10.6. Podsumowanie ............................................................................................................................ 300
301
11.1. Zrozumienie REST .................................................................................................................... 302
11.1.1. Fundamenty REST ..................................................................................................... 302
11.1.2. Obsïuga REST w Springu .......................................................................................... 303
11.2. Tworzenie kontrolerów korzystajÈcych z zasobów ................................................................. 303
11.2.1. Kontroler niezgodny z konwencjÈ REST pod lupÈ ................................................... 304
11.2.2. Obsïuga adresów URL typu RESTful ........................................................................ 305
11.2.3. Czasowniki REST ....................................................................................................... 308
11.3. Reprezentacja zasobów ............................................................................................................. 311
11.3.1. Negocjowanie reprezentacji zasobu ........................................................................... 311
11.3.2. Praca z konwerterami komunikatów HTTP .............................................................. 314
11.4. Tworzenie klientów REST ........................................................................................................ 317
11.4.1. Operacje szablonu RestTemplate ............................................................................... 319
11.4.2. Pobieranie zasobów za pomocÈ GET ......................................................................... 320
11.4.3. Umieszczanie zasobów na serwerze za pomocÈ PUT ............................................... 322
11.4.4. Usuwanie zasobów za pomocÈ DELETE .................................................................. 324
11.4.5. Wysyïanie danych zasobu za pomocÈ POST ............................................................. 325
11.4.6. Wymiana zasobów ....................................................................................................... 327
11.5. Wysyïanie formularzy typu RESTful ....................................................................................... 329
11.5.1. Umieszczanie ukrytych pól metod w kodzie za pomocÈ JSP ................................... 330
11.5.2. Demaskowanie rzeczywistego ĝÈdania ...................................................................... 330
11.6. Podsumowanie ............................................................................................................................ 332
333
12.1. Krótki wstÚp do JMS .................................................................................................................. 334
12.1.1. Architektura JMS ........................................................................................................ 335
12.1.2. Szacowanie korzyĂci zwiÈzanych z uĝyciem JMS ..................................................... 337
12.2. Konfiguracja brokera komunikatów w Springu ..................................................................... 338
12.2.1. Tworzenie fabryki poïÈczeñ ........................................................................................ 339
12.2.2. Deklaracja miejsca docelowego komunikatów ActiveMQ ........................................ 340
12.3. Szablon JMS Springa ................................................................................................................. 340
12.3.1. Kod JMS a obsïuga wyjÈtków ..................................................................................... 341
12.3.2. Praca z szablonami JMS .............................................................................................. 342
12.4. Tworzenie obiektów POJO sterowanych komunikatami ....................................................... 347
12.4.1. Tworzenie odbiorcy komunikatów ............................................................................. 348
12.4.2. Konfiguracja odbiorców komunikatów ...................................................................... 349
12.5. Uĝywanie RPC opartego na komunikatach ............................................................................. 350
12.5.1. Praca z RPC opartym na komunikatach w Springu .................................................. 350
12.5.2. Asynchroniczne RPC z Lingo ..................................................................................... 352
12.6. Podsumowanie ............................................................................................................................ 354
10
Spis treĂci
Rozdziaï 14. Pozostaïe zagadnienia
Rozdziaï 13. ZarzÈdzanie komponentami Springa za pomocÈ JMX
357
13.1. Eksportowanie komponentów Springa w formie MBean ...................................................... 358
13.1.1. UdostÚpnianie metod na podstawie nazwy ............................................................... 361
13.1.2. Uĝycie interfejsów do definicji operacji i atrybutów komponentu zarzÈdzanego ...... 363
13.1.3. Praca z komponentami MBean sterowanymi adnotacjami ....................................... 364
13.1.4. PostÚpowanie przy konfliktach nazw komponentów zarzÈdzanych ......................... 365
13.2. Zdalny dostÚp do komponentów zarzÈdzanych ...................................................................... 366
13.2.1. UdostÚpnianie zdalnych komponentów MBean ........................................................ 367
13.2.2. DostÚp do zdalnego komponentu MBean ................................................................. 367
13.2.3. Obiekty poĂredniczÈce komponentów zarzÈdzanych ................................................ 369
13.3. Obsïuga powiadomieñ ............................................................................................................... 370
13.3.1. Odbieranie powiadomieñ ........................................................................................... 371
13.4. Podsumowanie ............................................................................................................................ 372
373
14.1. WyodrÚbnianie konfiguracji ..................................................................................................... 374
14.1.1. ZastÚpowanie symboli zastÚpczych we wïaĂciwoĂciach ............................................ 374
14.1.2. Nadpisywanie wïaĂciwoĂci ......................................................................................... 377
14.1.3. Szyfrowanie zewnÚtrznych wïaĂciwoĂci .................................................................... 378
14.2. WiÈzanie obiektów JNDI .......................................................................................................... 380
14.2.1. Praca z tradycyjnym JNDI ......................................................................................... 380
14.2.2. Wstrzykiwanie obiektów JNDI .................................................................................. 382
14.2.3. WiÈzanie komponentów EJB w Springu ................................................................... 385
14.3. Wysyïanie wiadomoĂci e-mail ................................................................................................... 386
14.3.1. Konfiguracja komponentu wysyïajÈcego pocztÚ ........................................................ 386
14.3.2. Budowa wiadomoĂci e-mail ........................................................................................ 388
14.4. Planowanie zadañ wykonywanych w tle .................................................................................. 392
14.4.1. Deklaracja zaplanowanych metod .............................................................................. 393
14.4.2. Deklaracja metod asynchronicznych ......................................................................... 395
14.5. Podsumowanie ............................................................................................................................ 396
14.6. Koniec…? .................................................................................................................................... 396
Skorowidz
399
Aspektowy Spring
W tym rozdziale omówimy:
Q Podstawy programowania aspektowego
Q Tworzenie aspektów z POJO
Q Stosowanie adnotacji @AspectJ
Q Wstrzykiwanie zaleĪnoĞci do aspektów AspectJ
Gdy piszÚ ten rozdziaï, w Teksasie (gdzie mieszkam) mamy od kilku dni rekordowo
wysokie temperatury. Jest strasznie gorÈco. Podczas takiej pogody klimatyzacja jest
koniecznoĂciÈ. Jednak wadÈ klimatyzacji jest zuĝycie energii elektrycznej, a za energiÚ
elektrycznÈ trzeba zapïaciÊ. Niewiele moĝemy zrobiÊ w celu unikniÚcia wydatków na
to, by mieszkaÊ w chïodnych i komfortowych warunkach. To dlatego w kaĝdym domu
jest zamontowany licznik energii elektrycznej, który rejestruje wszystkie zuĝyte kilo-
waty, i raz w miesiÈcu ktoĂ przychodzi odczytaÊ ten licznik, aby zakïad energetyczny
dokïadnie wiedziaï, jaki wystawiÊ nam rachunek.
Teraz wyobraěmy sobie, co by siÚ staïo, gdyby taki licznik zniknÈï i nikt nie przy-
chodziï, by sprawdziÊ nasze zuĝycie energii elektrycznej. Zaïóĝmy, ĝe do kaĝdego
wïaĂciciela domu naleĝaïoby skontaktowanie siÚ z zakïadem energetycznym i zgïosze-
nie swojego zuĝycia energii. ChoÊ jest moĝliwe, ĝe jakiĂ obsesyjny wïaĂciciel domu
uwaĝnie rejestrowaïby kaĝde uĝycie Ăwiatïa, telewizji czy klimatyzacji, wiÚkszoĂÊ by
siÚ tym nie przejmowaïa. WiÚkszoĂÊ podaïaby swoje przybliĝone zuĝycie, a niektórzy nie
zgïosiliby zuĝycia w ogóle. Sprawdzanie zuĝycia energii byïoby kïopotliwe, a pokusa, by
nie zapïaciÊ, mogïaby okazaÊ siÚ zbyt silna.
108
ROZDZIAà 4. Aspektowy Spring
Ta forma systemu pïatnoĂci za energiÚ elektrycznÈ mógïaby byÊ Ăwietna dla klientów,
lecz byïaby daleka od ideaïu z punktu widzenia zakïadów energetycznych. To dlatego
wszyscy mamy w domu liczniki energii i dlatego raz w miesiÈcu ktoĂ zaglÈda, by odczytaÊ
licznik i poinformowaÊ zakïad energetyczny o zuĝyciu.
Niektóre funkcje systemów oprogramowania sÈ podobne do liczników energii elek-
trycznej w naszych domach. Funkcje te muszÈ byÊ stosowane w wielu miejscach w naszej
aplikacji, lecz byïoby niewygodne, gdybyĂmy musieli wywoïywaÊ je w kaĝdym miejscu.
Kontrola zuĝycia energii elektrycznej jest waĝnÈ funkcjÈ, lecz nie zajmuje najwyĝ-
szej pozycji w ĂwiadomoĂci wiÚkszoĂci wïaĂcicieli domów. Koszenie trawników, odku-
rzanie dywanów czy sprzÈtanie ïazienki to czynnoĂci, w które posiadacz domu jest
aktywnie zaangaĝowany. Natomiast kontrola zuĝycia elektrycznoĂci w domu jest z punktu
widzenia wïaĂciciela domu czynnoĂciÈ pasywnÈ (choÊ byïoby cudownie, gdyby kosze-
nie trawników teĝ byïo czynnoĂciÈ pasywnÈ — zwïaszcza w takie gorÈce dni).
W oprogramowaniu niektóre czynnoĂci sÈ powszechne w wiÚkszoĂci aplikacji. Reje-
strowanie transakcji, ich bezpieczeñstwo i zarzÈdzanie nimi sÈ waĝne, lecz czy powinny
byÊ czynnoĂciami, w których aktywnie uczestniczÈ obiekty naszej aplikacji? Czy moĝe
lepiej by byïo, aby obiekty naszej aplikacji pozostaïy skoncentrowane na problemach
z dziedziny biznesowej, do jakich zostaïy zaprojektowane, i pozostawiïy pewne aspekty
do obsïugi przez kogoĂ innego?
Funkcje, które przenikajÈ wiele miejsc w aplikacji, noszÈ w branĝy programistycznej
nazwÚ zagadnieñ przecinajÈcych. W typowej sytuacji takie zagadnienia przecinajÈce
sÈ koncepcyjnie rozdzielone od biznesowej logiki aplikacji (choÊ czÚsto bezpoĂrednio
w niÈ wbudowane). Oddzielenie zagadnieñ przecinajÈcych od logiki biznesowej jest
miejscem, gdzie do pracy wïÈcza siÚ programowanie aspektowe (AOP).
W rozdziale 2. nauczyliĂmy siÚ, jak uĝywaÊ wstrzykiwania zaleĝnoĂci do zarzÈdza-
nia obiektami naszej aplikacji i ich konfigurowania. Podobnie jak DI pozwala rozdzieliÊ
od siebie poszczególne obiekty aplikacji, AOP pozwala oddzieliÊ zagadnienia przecinajÈce
od obiektów, których one dotyczÈ.
Logowanie jest popularnym przykïadem zastosowania aspektów. Jednak nie jest to
jedyne zastosowanie, w którym korzystne bÚdzie uĝycie aspektów. Podczas lektury tej
ksiÈĝki zobaczymy kilka praktycznych zastosowañ aspektów, w tym transakcje deklara-
cyjne, bezpieczeñstwo oraz pamiÚÊ podrÚcznÈ.
W tym rozdziale zostanie omówiona obsïuga aspektów w Springu, w tym sposób
deklarowania zwykïych klas, aby staïy siÚ aspektami, oraz moĝliwoĂÊ zastosowania adno-
tacji podczas tworzenia aspektów. Dodatkowo dowiemy siÚ, w jaki sposób przy uĝyciu
AspectJ — innej popularnej implementacji AOP — moĝemy uzupeïniÊ dziaïanie Ăro-
dowiska AOP Springa. Lecz najpierw, zanim siÚ zajmiemy transakcjami, bezpieczeñ-
stwem i pamiÚciÈ podrÚcznÈ, dowiedzmy siÚ, w jaki sposób aspekty sÈ implementowane
w Springu, zaczynajÈc od paru zupeïnych podstaw AOP.
4.1.
Czym jest programowanie aspektowe
Jak wczeĂniej wspomnieliĂmy, aspekty pomagajÈ zamykaÊ w moduïach zagadnienia
przecinajÈce. W skrócie, zagadnienie przecinajÈce moĝna opisaÊ jako dowolny mecha-
nizm, którego wpïyw jest uĝywany na wielu miejscach w aplikacji. Bezpieczeñstwo na
4.1.
Czym jest programowanie aspektowe
109
przykïad jest zagadnieniem przecinajÈcym, w tym sensie, ĝe wiele metod w aplikacji
moĝe podlegaÊ stosowaniu reguï bezpieczeñstwa. Na rysunku 4.1 pokazano obrazowÈ
ilustracjÚ zagadnieñ przecinajÈcych.
Rysunek 4.1. Aspekty zamykają
w moduáach zagadnienia przecinające,
które dotyczą logiki zawartej w wielu
spoĞród obiektów aplikacji
Na rysunku 4.1 pokazano typowÈ aplikacjÚ, która jest podzielona na moduïy. Gïównym
zadaniem kaĝdego z moduïów jest realizowanie usïug ze swojej szczególnej dziedziny.
Lecz kaĝdy moduï potrzebuje takĝe podobnych mechanizmów pomocniczych, takich
jak bezpieczeñstwo czy zarzÈdzanie transakcjami.
PopularnÈ obiektowÈ technikÈ ponownego uĝycia tej samej funkcjonalnoĂci jest
stosowanie dziedziczenia albo delegacji. Ale dziedziczenie moĝe prowadziÊ do zbu-
rzenia hierarchii obiektów, jeĂli ta sama klasa bazowa jest stosowana w caïej aplikacji.
Z kolei stosowanie delegacji bywa uciÈĝliwe, poniewaĝ moĝe byÊ potrzebne skompli-
kowane wywoïanie delegacji.
Aspekty stanowiÈ alternatywÚ dla dziedziczenia i delegacji, która w wielu sytuacjach
moĝe byÊ bardziej eleganckim rozwiÈzaniem. KorzystajÈc z techniki AOP, nadal defi-
niujemy popularne mechanizmy w jednym miejscu, lecz za pomocÈ deklaracji definiu-
jemy, gdzie i jak mechanizmy te zostanÈ zastosowane, bez koniecznoĂci modyfikowania
klasy, do której majÈ zastosowanie nowe mechanizmy. OdtÈd zagadnienia przekrojowe
moĝemy zamknÈÊ w moduïach w postaci specjalnych klas zwanych aspektami. WynikajÈ
z tego dwie korzyĂci. Po pierwsze, logika dla kaĝdego zagadnienia znajduje siÚ teraz
w jednym miejscu, zamiast byÊ rozrzuconÈ po caïym kodzie. Po drugie, nasze moduïy
usïugowe bÚdÈ teraz bardziej uporzÈdkowane, poniewaĝ zawierajÈ jedynie kod dotyczÈcy
ich gïównego zadania (albo podstawowych funkcji), zaĂ zagadnienia drugorzÚdne zostaïy
przeniesione do aspektów.
4.1.1. Definiujemy terminologiĊ dotyczącą AOP
Podobnie jak w przypadku innych technologii, wraz z rozwojem AOP powstaï specyficzny
ĝargon opisujÈcy tÚ technikÚ programistycznÈ. Aspekty sÈ czÚsto opisywane za pomocÈ
pojÚÊ takich jak „porada”, „punkt przeciÚcia” czy „punkt zïÈczenia”. Na rysunku 4.2
pokazano, jak sÈ ze sobÈ powiÈzane te zagadnienia.
Niestety, wiele spoĂród pojÚÊ uĝywanych do opisywania AOP jest dalekie od
intuicyjnoĂci. SÈ one jednak obecnie czÚĂciÈ pojÚcia „programowanie aspektowe”
i musimy siÚ z nimi zapoznaÊ w celu zrozumienia tej nowej techniki programistycznej.
Zanim przejdziemy do praktyki, nauczmy siÚ jÚzyka, w którym bÚdziemy rozmawiaÊ.
110
ROZDZIAà 4. Aspektowy Spring
PORADA
Gdy osoba odczytujÈca licznik pokaĝe siÚ
w naszym domu, jej zadaniem jest po-
informowanie zakïadu energetycznego
o wskazywanej liczbie kilowatogodzin.
Z pewnoĂciÈ osoba ta ma listÚ domów,
które musi odwiedziÊ, zaĂ informacje,
które dostarcza zakïadowi energetyczne-
mu, sÈ waĝne. Lecz gïównym zadaniem
osoby odczytujÈcej liczniki jest sama
czynnoĂÊ notowania zuĝycia energii.
Podobnie, aspekty majÈ gïówne zada-
nie — czynnoĂÊ, której wykonanie jest
celem ich istnienia. W terminologii pro-
gramowania aspektowego zadanie aspektu
jest nazywane poradÈ.
Rysunek 4.2. FunkcjonalnoĞü aspektu
(porada) jest wplatana do wykonania
programu w jednym lub wiĊcej punktach
záączenia
Porada jest dla aspektu definicjÈ zarówno czynnoĂci, która ma zostaÊ wykonana, jak
i wïaĂciwego momentu jej wykonania. Czy aspekt powinien byÊ wykonany przed wywo-
ïaniem metody? Po jej wykonaniu? Zarówno przed wywoïaniem metody, jak i po niej?
A moĝe tylko wtedy, gdy metoda zgïosi wyjÈtek? Aspekty w Springu mogÈ dziaïaÊ z piÚ-
cioma rodzajami porad:
Q Before — FunkcjonalnoĂÊ porady jest wykonywana przed wywoïaniem metody
z poradÈ.
Q After — FunkcjonalnoĂÊ porady jest wykonywana po zakoñczeniu dziaïania
metody z poradÈ, niezaleĝnie od wyniku jej dziaïania.
Q After-returning — FunkcjonalnoĂÊ porady jest wykonywana po prawidïowym
Q After-throwing — FunkcjonalnoĂÊ porady jest wykonywana po zgïoszeniu
zakoñczeniu metody z poradÈ.
wyjÈtku przez metodÚ z poradÈ.
Q Around — Porada realizuje tÚ samÈ funkcjonalnoĂÊ zarówno przed wywoïaniem,
jak i po zakoñczeniu metody z poradÈ.
PUNKTY ZàĄCZENIA
Zakïad energetyczny obsïuguje wiele domów, prawdopodobnie wrÚcz caïe miasto.
W kaĝdym domu zamontowany jest licznik energii elektrycznej, zatem kaĝdy dom jest
potencjalnym celem dla osoby odczytujÈcej liczniki. Potencjalnie osoba taka mogïaby
odczytywaÊ wiele róĝnych przyrzÈdów pomiarowych, lecz w ramach swoich obowiÈzków
sïuĝbowych powinna przyjÈÊ za cel wïaĂnie liczniki energii zamontowane w domach.
W podobny sposób w naszej aplikacji mogÈ byÊ tysiÈce miejsc, w których moglibyĂmy
zastosowaÊ poradÚ. Miejsca te sÈ nazywane punktami zïÈczenia. Punkt zïÈczenia jest
takÈ pozycjÈ w przebiegu wykonania programu, w której moĝe zostaÊ wpiÚty aspekt.
Takim punktem moĝe byÊ wywoïanie metody, zgïoszenie wyjÈtku czy nawet modyfi-
kacja zawartoĂci pola. SÈ to pozycje, w których kod aspektu moĝe zostaÊ wïÈczony
w normalny przebieg dziaïania naszej aplikacji, wzbogacajÈc tym jej dziaïanie.
4.1.
Czym jest programowanie aspektowe
111
PUNKTY PRZECIĉCIA
Nie jest moĝliwe, by jedna osoba odczytujÈca liczniki zdoïaïa odwiedziÊ wszystkie domy,
którym elektrycznoĂÊ dostarcza ten sam zakïad energetyczny. Pojedynczej osobie jest
przypisany jedynie pewien podzbiór wszystkich domów. Podobnie porada nie musi
koniecznie doïÈczaÊ aspektu do kaĝdego punktu zïÈczenia w aplikacji. Punkty przeciÚcia
pozwalajÈ zawÚziÊ listÚ punktów zïÈczenia, do których zastosowany bÚdzie aspekt.
JeĂli porada definiowaïa czynnoĂÊ i moment jej wykonania przez aspekt, to punkty
przeciÚcia definiujÈ miejsce, w którym czynnoĂÊ ta zostanie wykonana. Definicja punktu
przeciÚcia dopasowuje jeden lub wiÚcej punktów zïÈczenia, w których naleĝy wpleĂÊ
poradÚ. CzÚsto okreĂlamy takie punkty przeciÚcia za pomocÈ jawnego wskazania nazw
metod i klas albo za pomocÈ wyraĝeñ regularnych, które dopasowujÈ do wzorców nazwy
klas i metod. Niektóre frameworki aspektowe pozwalajÈ na tworzenie dynamicznych
punktów przeciÚcia, w których decyzja, czy zastosowaÊ poradÚ, jest podejmowana w trak-
cie dziaïania, na przykïad na podstawie wartoĂci parametrów metod.
ASPEKTY
Gdy osoba odczytujÈca liczniki rozpoczyna dzieñ pracy, wie zarówno, co naleĝy do jej
obowiÈzków (kontrola zuĝycia energii elektrycznej), jak równieĝ z których domów powinna
zbieraÊ tÚ informacjÚ. Zatem wie ona wszystko, co potrzeba, by wywiÈzaÊ siÚ ze swoich
obowiÈzków.
Aspekt jest sumÈ porady i punktów przeciÚcia. WziÚte razem porada i punkty przeciÚ-
cia definiujÈ wszystko, co moĝna powiedzieÊ o aspekcie — jakÈ czynnoĂÊ wykonuje,
gdzie i kiedy.
WPROWADZENIA
Wprowadzenie pozwala nam dodawaÊ nowe metody lub atrybuty do istniejÈcych klas.
Na przykïad moĝemy skonstruowaÊ klasÚ z poradÈ, o nazwie Auditable. BÚdzie ona
przechowywaïa informacjÚ o momencie ostatniej modyfikacji obiektu. Moĝe to byÊ klasa
tak prosta, ĝe bÚdzie posiadaïa tylko jednÈ metodÚ, nazwanÈ setLastModified(Date)
i zmiennÈ o zasiÚgu instancji, która bÚdzie przechowywaïa stan tej klasy. TakÈ nowÈ
metodÚ i zmiennÈ moĝemy wprowadziÊ do istniejÈcych klas bez koniecznoĂci ich mody-
fikowania, wzbogacajÈc je o nowe dziaïanie i zmiennÈ stanu.
WPLATANIE
Wplatanie jest procesem zastosowania aspektu do obiektu docelowego w celu utwo-
rzenia nowego obiektu z poĂrednikiem. Aspekty sÈ wplatane do docelowych obiektów
we wskazanych punktach zïÈczenia. Wplatanie moĝe mieÊ miejsce w róĝnych momen-
tach cyklu ĝycia docelowego obiektu:
Q W czasie kompilacji — Aspekty zostajÈ wplecione, gdy klasa docelowa jest
kompilowana. W tym celu potrzebny jest specjalny kompilator. WplatajÈcy
kompilator w AspectJ wplata aspekty w ten sposób.
Q W czasie ïadowania klasy — Aspekty zostajÈ wplecione, gdy klasa docelowa
jest ïadowana do maszyny wirtualnej Javy (JVM). W tym celu potrzebny jest
specjalny ClassLoader, który rozszerza kod bajtowy docelowej klasy, zanim
112
ROZDZIAà 4. Aspektowy Spring
zostanie ona wprowadzona do aplikacji. Opcja wplatania w czasie ïadowania
(ang. load-time weaving, LTW) wprowadzona w wersji 5 AspectJ realizuje
wplatanie aspektów w ten sposób.
Q W czasie dziaïania — Aspekty zostajÈ wplecione w jakimĂ momencie podczas
dziaïania aplikacji. W typowej sytuacji kontener aspektowy bÚdzie dynamicznie
generowaï obiekt poĂredniczÈcy, który zostanie poïÈczony z obiektem docelowym
za pomocÈ delegacji podczas wplatania aspektów. Z tego sposobu korzysta
Spring AOP podczas wplatania aspektów.
To wiele nowych pojÚÊ, z którymi trzeba siÚ zapoznaÊ. WracajÈc do rysunku 4.2, zoba-
czymy, ĝe porada zawiera zachowanie zagadnienia przecinajÈcego, które ma byÊ wïÈczone
do obiektów aplikacji. Punktami zïÈczenia sÈ wszystkie punkty w przebiegu dziaïania
aplikacji, które sÈ potencjalnymi miejscami zastosowania porady. Najwaĝniejszym, co
naleĝy tu sobie uĂwiadomiÊ, jest fakt, ĝe punkty przeciÚcia definiujÈ, które punkty zïÈ-
czenia bÚdÈ brane pod uwagÚ.
Gdy juĝ siÚ troszkÚ oswoiliĂmy z najbardziej podstawowÈ czÚĂciÈ terminologii doty-
czÈcej programowania aspektowego, przekonajmy siÚ, jak te podstawowe koncepcje AOP
zostaïy zaimplementowane w Springu.
4.1.2. Obsáuga programowania aspektowego w Springu
Nie wszystkie aspektowe frameworki sÈ skonstruowane tak samo. MogÈ siÚ róĝniÊ tym,
jak bogaty model punktów zïÈczeñ posiadajÈ. Niektóre pozwalajÈ stosowaÊ porady na
poziomie modyfikacji pól, podczas gdy inne udostÚpniajÈ jedynie punkty zïÈczeñ zwiÈzane
z wywoïaniem metod. MogÈ siÚ takĝe róĝniÊ sposobem i momentem wplatania aspektów.
Niezaleĝnie od konkretnego przypadku, moĝliwoĂÊ tworzenia punktów przeciÚcia, defi-
niujÈcych punkty zïÈczenia, w których powinny zostaÊ wplecione aspekty, jest tym, co
stanowi aspektowy framework.
Wiele siÚ zmieniïo w branĝy frameworków aspektowych przez ostatnie kilka lat.
Zostaïy poczynione porzÈdki, w wyniku których niektóre spoĂród frameworków zostaïy
poïÈczone ze sobÈ, z kolei inne zaczynajÈ zanikaÊ. W roku 2005 projekt AspectWerkz
zostaï poïÈczony z AspectJ, co byïo ostatniÈ istotnÈ zmianÈ w Ăwiecie AOP, pozosta-
wiajÈc nam do wyboru trzy dominujÈce frameworki aspektowe:
Q AspectJ (http://eclipse.org/aspectj),
Q
Q Spring AOP (http://www.springframework.org).
JBoss AOP (http://www.jboss.org/jbossaop),
Poniewaĝ ksiÈĝka ta jest poĂwiÚcona frameworkowi Spring, skupimy siÚ na Spring AOP.
Mimo to wystÚpuje wiele podobieñstw miÚdzy projektami Spring i AspectJ, zaĂ obsïuga
AOP w Springu zawiera wiele zapoĝyczeñ z projektu AspectJ.
Obsïuga AOP w Springu ma cztery odmiany:
Q Klasyczna obsïuga AOP w Springu na bazie obiektów poĂredniczÈcych.
Q Aspekty sterowane adnotacjÈ @AspectJ.
Q Aspekty zbudowane z „czystych” POJO.
Q Wstrzykiwane aspekty z AspektJ (dostÚpne we wszystkich wersjach Springa).
4.1.
Czym jest programowanie aspektowe
113
Pierwsze trzy pozycje sÈ wïaĂciwie odmianami obsïugi AOP przez Springa na bazie
obiektów poĂredniczÈcych. W efekcie obsïuga AOP w Springu jest ograniczona do prze-
chwytywania metod. JeĂli potrzebujemy w Springu rozszerzonego przechwytywania
prostych metod (na przykïad przechwytywania konstruktora albo wïaĂciwoĂci), bÚdziemy
musieli rozwaĝyÊ implementacjÚ aspektów w AspectJ, byÊ moĝe korzystajÈc ze wstrzyki-
wania zaleĝnoĂci w Springu, by wstrzyknÈÊ komponenty Springa do aspektów w AspectJ.
Co takiego? Nie bĊdzie omówienia klasycznego AOP w Springu?
Sáowo klasyczne zwykle budzi pozytywne skojarzenia. Klasyczne samochody, klasyczny
turniej golfowy czy teĪ klasyczna Coca-Cola — wszystkie są czymĞ dobrym.
Lecz klasyczny model programowania aspektowego w Springu wcale nie jest zbyt
dobry. OczywiĞcie, byá czymĞ Ğwietnym jak na swoje czasy. Lecz obecnie istnieją
w Springu znacznie bardziej uporządkowane i áatwiejsze sposoby pracy z aspektami.
W porównaniu do prostego deklaracyjnego modelu AOP i AOP opartego na adnota-
cjach klasyczny model AOP w Springu robi wraĪenie ociĊĪaáego i nadmiernie skom-
plikowanego. BezpoĞrednie wykorzystanie ProxyFactoryBean moĪe byü mĊczące.
Zatem zdecydowaáem, Īe do bieĪącego wydania tej ksiąĪki nie wáączĊ w ogóle omó-
wienia klasycznego AOP w Springu. JeĞli naprawdĊ ciekawi ciĊ, Czytelniku, jak dziaáa
ten model AOP, moĪesz sprawdziü w pierwszych dwóch wydaniach. Lecz sądzĊ, Īe prze-
konasz siĊ, iĪ praca z nowymi modelami AOP w Springu jest znacznie áatwiejsza.
W tym rozdziale dowiemy siÚ wiÚcej o powyĝszych technikach aspektowych w Springu.
Jednak zanim rozpoczniemy, waĝne, byĂmy zrozumieli kilka kluczowych zagadnieñ
w aspektowym frameworku Spring.
PORADA SPRINGA JEST ZAPISANA W JAVIE
Wszystkie porady, jakie utworzymy w Springu, sÈ zapisane w standardowych klasach
Javy. W ten sposób czerpiemy korzyĂÊ z moĝliwoĂci konstruowania naszych aspektów
w tym samym zintegrowanym Ărodowisku programistycznym (IDE), którego na co dzieñ
uĝywamy do pisania programów w Javie. Co wiÚcej, punkty przeciÚcia, które definiujÈ
miejsca, gdzie porady powinny zostaÊ zastosowane, zwykle zapisujemy w jÚzyku XML,
jako czÚĂÊ naszego pliku konfiguracji Springa. To oznacza, ĝe zarówno kod aspektów,
jak i skïadnia konfiguracji bÚdÈ naturalne dla programistów Javy.
Inaczej jest w AspectJ. ChoÊ obecnie AspectJ obsïuguje juĝ aspekty oparte na ad-
notacjach, AspectJ pojawiï siÚ takĝe jako rozszerzenie jÚzyka Java. Takie podejĂcie ma
zarówno zalety, jak i wady. Posiadanie specjalizowanego jÚzyka do obsïugi aspektów
zwiÚksza moĝliwoĂci takiego jÚzyka i pozwala na precyzyjniejszÈ kontrolÚ jego zacho-
wania, a takĝe bogatszy zestaw narzÚdzi aspektowych. Lecz osiÈgamy to kosztem ko-
niecznoĂci nauki nowego narzÚdzia i nowej skïadni.
SPRING DOàĄCZA PORADY DO OBIEKTÓW W TRAKCIE PRACY
Spring wplata aspekty do zarzÈdzanych przez niego komponentów w trakcie pracy,
opakowujÈc je w klasy poĂredniczÈce. Jak pokazano na rysunku 4.3, klasa poĂredniczÈca
zawiera docelowy komponent, przechwytuje wywoïania metod z poradÈ i przekiero-
wuje wywoïania tych metod do komponentu docelowego.
114
ROZDZIAà 4. Aspektowy Spring
Rysunek 4.3. Aspekty w Springu zostaáy zaimplementowane
jako obiekty poĞredniczące, które opakowują obiekt docelowy.
Obiekt poĞredniczący przechwytuje wywoáania metod, wykonuje
dodatkową logikĊ aspektu, a nastĊpnie wywoáuje metodĊ
docelową
W czasie pomiÚdzy przechwyceniem przez obiekt poĂredniczÈcy wywoïania metody
a momentem wywoïania metody komponentu docelowego obiekt poĂredniczÈcy reali-
zuje logikÚ aspektu.
Spring nie tworzy obiektu z poĂrednikiem, dopóki aplikacja nie bÚdzie potrzebowaïa
okreĂlonego komponentu. JeĂli korzystamy z ApplicationContext, obiekt z poĂredni-
kiem zostanie utworzony, gdy kontekst bÚdzie ïadowaï wszystkie naleĝÈce do niego
komponenty z BeanFactory. Poniewaĝ Spring tworzy obiekty poĂredniczÈce w czasie
dziaïania, korzystanie z AOP w Springu nie zmusza nas do stosowania specjalnego kom-
pilatora, który umoĝliwiaïby wplatanie aspektów.
SPRING OBSàUGUJE JEDYNIE PUNKTY ZàĄCZENIA ZWIĄZANE Z METODAMI
Jak wspomnieliĂmy wczeĂniej, w poszczególnych implementacjach AOP stosowane sÈ
róĝne modele punktów zïÈczenia. Poniewaĝ Spring bazuje na dynamicznych obiektach
poĂredniczÈcych, obsïuguje tylko punkty zïÈczenia zwiÈzane z metodami. W tym róĝ-
ni siÚ od niektórych innych frameworków aspektowych, takich jak AspectJ czy JBoss,
które poza punktami zïÈczenia zwiÈzanymi z metodami oferujÈ takĝe obsïugÚ punktów
zïÈczenia zwiÈzanych z polami oraz z konstruktorami. NieobecnoĂÊ w Springu punktów
przeciÚcia zwiÈzanych z polami uniemoĝliwia nam tworzenie porad o bardzo duĝej
precyzji, takich jak przejÚcie aktualizacji pola w obiekcie. ZaĂ bez punktów przeciÚcia
zwiÈzanych z konstruktorami nie dysponujemy sposobem, by zastosowaÊ poradÚ pod-
czas tworzenia instancji beana.
Przechwytywanie wywoïañ metod powinno zaspokoiÊ wiÚkszoĂÊ, jeĂli nie wszystkie,
z naszych potrzeb. JeĂli okaĝe siÚ, ĝe potrzebujemy czegoĂ wiÚcej niĝ tylko przechwyty-
wanie wywoïañ metod, bÚdziemy mogli uzupeïniÊ funkcjonalnoĂÊ AOP w Springu za
pomocÈ AspectJ.
Teraz mamy juĝ ogólne pojÚcie, do czego sïuĝy programowanie aspektowe i w jaki
sposób jest obsïugiwane przez Springa. Nadszedï czas, by zakasaÊ rÚkawy i wziÈÊ siÚ za
tworzenie aspektów w Springu. Zacznijmy od deklaracyjnego modelu AOP w Springu.
4.2.
Wybieramy punkty zïÈczenia za pomocÈ punktów przeciÚcia
115
4.2. Wybieramy punkty záączenia
za pomocą punktów przeciĊcia
Jak wczeĂniej wspominaliĂmy, punktów przeciÚcia uĝywamy do wskazania miejsca,
w którym powinna zostaÊ zastosowana porada aspektu. Obok porady, punkty przeciÚcia
stanowiÈ najbardziej podstawowe skïadniki aspektu. Jest zatem waĝne, byĂmy wiedzieli,
w jaki sposób wiÈzaÊ punkty przeciÚcia.
ProgramujÈc aspektowo w Springu, definiujemy punkty przeciÚcia za pomocÈ
pochodzÈcego z frameworka AspectJ jÚzyka wyraĝeñ punktów przeciÚcia. JeĂli jesteĂmy
juĝ zaznajomieni ze Ărodowiskiem AspectJ, wówczas definiowanie punktów przeciÚcia
w Springu wyda siÚ nam naturalne. Lecz w razie gdyby AspectJ byï dla nas framewor-
kiem nowym, ten podrozdziaï moĝe sïuĝyÊ jako szybki samouczek pisania punktów
przeciÚcia w stylu AspectJ. PoszukujÈcym bardziej szczegóïowego omówienia frame-
worka AspectJ oraz pochodzÈcego z tego frameworka jÚzyka wyraĝeñ punktów prze-
ciÚcia z caïego serca polecam drugie wydanie ksiÈĝki AspectJ in Action, którÈ napisaï
Ramnivas Laddad.
Najwaĝniejszym, co powinniĂmy wiedzieÊ na temat punktów przeciÚcia w stylu
AspectJ w zastosowaniu do programowania aspektowego w Springu, jest fakt obsïugi-
wania przez Springa jedynie podzbioru desygnatorów punktów przeciÚcia dostÚpnych
w AspectJ. Przypomnijmy sobie, ĝe Spring AOP bazuje na obiektach poĂredniczÈcych
i niektóre wyraĝenia opisujÈce punkty przeciÚcia niczego nie wnoszÈ dla programowania
aspektowego bazujÈcego na obiektach poĂredniczÈcych. W tabeli 4.1 zawarto zestawienie
desygnatorów punktów przeciÚcia pochodzÈcych z AspectJ, które sÈ obsïugiwane przez
Spring AOP.
Tabela 4.1. Spring do definiowania aspektów wykorzystuje jĊzyk wyraĪeĔ punktów
przeciĊcia pochodzący z AspectJ
Desygnator
w stylu AspectJ
Opis
args()
@args()
execution()
this()
target()
@target()
within()
@within()
@annotation
Ogranicza dopasowanie punktów záączenia do wywoáaĔ metod, których
argumenty są instancjami okreĞlonych typów.
Ogranicza dopasowanie punktów záączenia do wywoáaĔ metod, których
argumenty są opatrzone adnotacjami okreĞlonych typów.
Dopasowuje punkty záączenia, które są wywoáaniami metod.
Ogranicza dopasowanie punktów záączenia do takich, które posiadają
w obiekcie poĞredniczącym AOP referencjĊ do beana okreĞlonego typu.
Ogranicza dopasowanie punktów záączenia do takich, w których obiekt
docelowy jest instancją okreĞlonego typu.
Ogranicza dopasowanie do punktów záączenia, w których klasa wywoáywanego
obiektu jest opatrzona adnotacją okreĞlonego typu.
Ogranicza dopasowanie do punktów záączenia bĊdących instancjami
okreĞlonych typów.
Ogranicza dopasowanie do punktów záączenia bĊdących instancjami typów,
które są opatrzone okreĞloną adnotacją (w zastosowaniu dla Spring AOP
wywoáania metod zadeklarowanych w typach opatrzonych okreĞloną
adnotacją).
Ogranicza dopasowanie punktów záączenia do takich, w których obiekt bĊdący
przedmiotem dziaáania punktów záączenia jest opatrzony okreĞloną adnotacją.
116
ROZDZIAà 4. Aspektowy Spring
Próba uĝycia któregoĂ z desygnatorów pochodzÈcych z AspectJ, niewymienionego
w powyĝszej tabeli, bÚdzie skutkowaïa zgïoszeniem wyjÈtku IllegalArgumentException.
PrzeglÈdajÈc listÚ obsïugiwanych desygnatorów, zwróÊmy uwagÚ, ĝe execution jest
jedynym desygnatorem, który faktycznie realizuje dopasowanie. Wszystkich pozostaïych
uĝywamy do ograniczania takich dopasowañ. To znaczy, ĝe podstawowy jest desygnator
execution, którego uĝyjemy w kaĝdej definicji punktu przeciÚcia, jakÈ napiszemy. Pozo-
staïych bÚdziemy uĝywaÊ do ograniczania zasiÚgu punktu przeciÚcia.
4.2.1. Piszemy definicje punktów przeciĊcia
Przykïadowo moĝemy uĝyÊ wyraĝenia pokazanego na rysunku 4.4, by zastosowaÊ poradÚ
za kaĝdym wywoïaniem metody play(), naleĝÈcej do klasy Instrument.
Rysunek 4.4. Wybieramy metodĊ play(), zdefiniowaną w klasie Instrument,
za pomocą wyraĪenia punktu przeciĊcia w stylu AspectJ
UĝyliĂmy desygnatora execution(), by wybraÊ metodÚ play(), naleĝÈcÈ do klasy Instru
´ment. Specyfikacja metody rozpoczyna siÚ od gwiazdki, która oznacza, ĝe nie ma dla
nas znaczenia, jaki bÚdzie typ wartoĂci zwróconej przez metodÚ. NastÚpnie podajemy
peïnÈ, kwalifikowanÈ nazwÚ klasy oraz nazwÚ metody, którÈ chcemy wybraÊ. Dla listy
parametrów metody uĝyliĂmy podwójnej kropki (..), co oznacza, ĝe punkt przeciÚcia
moĝe wybraÊ dowolnÈ spoĂród metod play(), niezaleĝnie od tego, jakie parametry
przyjmujÈ poszczególne z nich.
Teraz zaïóĝmy, ĝe chcemy zawÚziÊ zasiÚg tego punktu przeciÚcia jedynie do pakietu
com.springinaction.springidol. W takiej sytuacji moĝemy ograniczyÊ dopasowanie,
dodajÈc do wyraĝenia desygnator within(), jak pokazano na rysunku 4.5.
Rysunek 4.5. Ograniczamy zasiĊg punktu przeciĊcia za pomocą
desygnatora within()
Zauwaĝmy, ĝe uĝyliĂmy operatora , by poïÈczyÊ desygnatory execution() oraz within()
za pomocÈ relacji koniunkcji (w której warunkiem dopasowania punktu przeciÚcia jest
dopasowanie obydwu desygnatorów). Podobnie, mogliĂmy uĝyÊ operatora ||, by utworzyÊ
relacjÚ alternatywy. Z kolei operator ! pozwala zanegowaÊ wynik dziaïania desygnatora.
4.3.
Deklarujemy aspekty w jÚzyku XML
117
Poniewaĝ znak jest symbolem specjalnym w jÚzyku XML, moĝemy swobodnie
zastÈpiÊ notacjÚ operatorem and, gdy zapisujemy specyfikacjÚ punktów przeciÚcia
w pliku konfiguracyjnym XML Springa. Podobnie, moĝemy uĝyÊ operatorów or oraz not,
zastÚpujÈc nimi, odpowiednio, notacjÚ || i !.
4.2.2. Korzystamy z desygnatora bean() w Springu
W wersji 2.5 Springa wprowadzono nowy desygnator bean(), rozszerzajÈcy listÚ zawartÈ
w tabeli 4.1. Pozwala on wskazywaÊ komponenty za pomocÈ ich nazw w wyraĝeniu
punktu przeciÚcia. Desygnator bean() przyjmuje jako argument nazwÚ komponentu
i ogranicza dziaïanie punktu przeciÚcia do tego konkretnego komponentu.
Przykïadowo, rozwaĝmy poniĝszy punkt przeciÚcia:
execution(* com.springinaction.springidol.Instrument.play()) and bean(eddie)
Informujemy tu Springa, ĝe chcemy zastosowaÊ poradÚ aspektu do wykonania metody
play() klasy Instrument, lecz ograniczajÈc siÚ do wywoïañ z komponentu o nazwie eddie.
MoĝliwoĂÊ zawÚĝenia punktu przeciÚcia do okreĂlonego komponentu moĝe byÊ cenna
w niektórych sytuacjach, lecz moĝemy takĝe uĝyÊ negacji, by zastosowaÊ aspekt do
wszystkich komponentów, z wyjÈtkiem posiadajÈcego okreĂlonÈ nazwÚ:
execution(* com.springinaction.springidol.Instrument.play()) and !bean(eddie)
W tym wypadku porada aspektu zostanie wpleciona do wszystkich komponentów, które
majÈ nazwÚ róĝnÈ od eddie.
Teraz, gdy omówiliĂmy podstawy pisania punktów przeciÚcia, zmierzmy siÚ z pisa-
niem porad i deklarowaniem aspektów, które bÚdÈ z tych punktów przeciÚcia korzystaïy.
4.3.
Deklarujemy aspekty w jĊzyku XML
JeĂli jesteĂ obeznany z klasycznym modelem programowania aspektowego w Springu,
wiesz, ĝe praca z ProxyFactoryBean jest bardzo niewygodna. Twórcy Springa zauwa-
ĝyli ten problem i postanowili udostÚpniÊ lepszy sposób na deklarowanie aspektów
w tym frameworku. Rezultat tych starañ znalazï siÚ w przestrzeni nazw aop Springa.
Zestawienie elementów konfiguracyjnych AOP umieszczono w tabeli 4.2.
W rozdziale 2., pokazujÈc przykïad wstrzykiwania zaleĝnoĂci, zorganizowaliĂmy
turniej talentów o nazwie Idol Springa. W przykïadzie tym utworzyliĂmy powiÈzania
dla kilku wykonawców, jako elementów bean , umoĝliwiajÈc im zademonstrowanie ich
uzdolnieñ. To wszystko byïo wspaniaïÈ rozrywkÈ. Lecz tego rodzaju przedsiÚwziÚcie
potrzebuje widowni albo bÚdzie bezcelowe.
Zatem, aby zilustrowaÊ dziaïanie Spring AOP, utwórzmy klasÚ Audience dla nasze-
go turnieju talentów. Funkcje widowni definiuje klasa z listingu 4.1.
Jak widzimy, klasa Audience niczym szczególnym siÚ nie wyróĝnia. Jest to podsta-
wowa klasa Javy, zawierajÈca kilka metod. Moĝemy takĝe zarejestrowaÊ tÚ klasÚ jako
beana w kontekĂcie aplikacji Springa:
bean id= audience
class= com.springinaction.springidol.Audience /
118
ROZDZIAà 4. Aspektowy Spring
Tabela 4.2. Elementy konfiguracyjne Spring AOP upraszczają deklaracjĊ aspektów
bazujących na POJO
Element konfiguracji AOP
Zastosowanie
aop:advisor
aop:after
aop:after-returning
aop:after-throwing
aop:around
aop:aspect
aop:aspect-autoproxy
aop:before
aop:config
aop:declare-parents
aop:pointcut
Definiuje doradcĊ aspektowego.
Definiuje aspektową poradĊ after (niezaleĪną od wyniku
dziaáania metody zaopatrzonej w poradĊ).
Definiuje aspektową poradĊ after-returning (po pomyĞlnym
zakoĔczeniu dziaáania metody).
Definiuje aspektową poradĊ after-throwing (po zgáoszeniu
wyjątku przez metodĊ).
Definiuje aspektową poradĊ around (zarówno przed
wykonaniem metody, jak i po zakoĔczeniu jej dziaáania).
Definiuje aspekt.
Przeáącza w tryb aspektów sterowanych adnotacjami z uĪyciem
@AspectJ.
Definiuje aspektową poradĊ before (przed wykonaniem
metody).
Element nadrzĊdnego poziomu w konfiguracji aspektowej.
WiĊkszoĞü elementów aop:* powinna znajdowaü siĊ
wewnątrz elementu aop:config .
Wprowadza do obiektów z poradą dodatkowe interfejsy,
implementowane w przezroczysty sposób.
Definiuje punkt przeciĊcia.
Listing 4.1. Klasa Audience dla naszego turnieju talentów
package com.springinaction.springidol;
public class Audience {
public void takeSeats() { Przed wystĊpem
System.out.println( Widzowie zajmujæ miejsca. );
}
p
Pobierz darmowy fragment (pdf)