informatyka spring w akcji wydanie iii craig walls ebook

background image
background image

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ść

background image

Spis tre!ci

Przedmowa ............................................................................................................................................... 11
Podzi"kowania .......................................................................................................................................... 13
O ksi#$ce ................................................................................................................................................... 15

C

Z !#

1. P

ODSTAWY FRAMEWORKA

S

PRING

Rozdzia% 1. Zrywamy si& do dzia%ania

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

1.2.1.

Pracujemy z kontekstem aplikacji ................................................................................ 37

1.2.2.

Cykl 'ycia komponentu ................................................................................................. 37

1.3. Podziwiamy krajobraz Springa ................................................................................................... 39

1.3.1.

Modu0y Springa ............................................................................................................. 39

1.3.2.

Rodzina projektów wokó0 Springa ............................................................................... 42

1.4. Co nowego w Springu .................................................................................................................. 46

1.4.1.

Co nowego w Springu 2.5? ........................................................................................... 46

1.4.2.

Co nowego w Springu 3.0? ........................................................................................... 47

1.4.3.

Co nowego w rodzinie projektów otaczaj#cych Springa? ........................................... 47

1.5. Podsumowanie .............................................................................................................................. 48

Rozdzia% 2. Tworzymy powi'zania mi&dzy komponentami

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 w0a(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'e8 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

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

6

Spis tre%ci

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

3.2.1.

Korzystamy z adnotacji @Autowired ........................................................................... 92

3.2.2.

Stosujemy automatyczne wi#zanie zgodne ze standardami,
korzystaj#c z adnotacji @Inject .................................................................................... 97

3.2.3.

Pos0ugujemy 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

Rozdzia% 4. Aspektowy Spring

107

4.1. Czym jest programowanie aspektowe ...................................................................................... 108

4.1.1.

Definiujemy terminologi, dotycz#c# AOP ................................................................ 109

4.1.2.

Obs0uga programowania aspektowego w Springu .................................................... 112

4.2. Wybieramy punkty z%'czenia za pomoc' punktów przeci&cia .............................................. 115

4.2.1.

Piszemy definicje punktów przeci,cia ....................................................................... 116

4.2.2.

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

4.4.1.

Tworzymy porad, around za pomoc# adnotacji ........................................................ 129

4.4.2.

Przekazujemy argumenty do porad konfigurowanych przez adnotacje ................... 130

4.4.3.

Tworzymy wprowadzenie za pomoc# adnotacji ........................................................ 131

4.5. Wstrzykujemy aspekty z AspectJ .............................................................................................. 132
4.6. Podsumowanie ............................................................................................................................ 135

C

Z !#

2. P

ODSTAWY APLIKACJI

S

PRINGA

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

5.1.3.

Klasy bazowe DAO ..................................................................................................... 145

5.2. Konfiguracja +ród%a danych ...................................................................................................... 147

5.2.1.

>ród0a danych JNDI ................................................................................................... 147

5.2.2.

>ród0a danych z pul# ................................................................................................... 147

5.2.3.

>ród0o danych oparte na sterowniku JDBC .............................................................. 149

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Spis tre%ci

7

5.3. U)ywanie JDBC w Springu ....................................................................................................... 149

5.3.1.

Kod JDBC a obs0uga wyj#tków .................................................................................. 150

5.3.2.

Praca z szablonami JDBC ........................................................................................... 153

5.4. 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

5.5.1.

Konfiguracja fabryki mened'erów encji .................................................................... 164

5.5.2.

Klasa DAO na bazie JPA ............................................................................................. 168

5.6. Podsumowanie ............................................................................................................................ 169

Rozdzia% 6. Zarz'dzanie transakcjami

171

6.1. Zrozumienie transakcji .............................................................................................................. 172

6.1.1.

Cztery s0owa kluczowe do zrozumienia transakcji .................................................... 173

6.1.2.

Zrozumienie obs0ugi zarz#dzania transakcjami w Springu ....................................... 174

6.2. Wybór mened)era transakcji .................................................................................................... 175

6.2.1.

Transakcje JDBC ........................................................................................................ 175

6.2.2.

Transakcje Hibernate .................................................................................................. 176

6.2.3.

Transakcje Java Persistence API ................................................................................ 177

6.2.4.

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

Rozdzia% 7. Budowanie aplikacji sieciowych za pomoc' Spring MVC

189

7.1. Wprowadzenie do Spring MVC ............................................................................................... 190

7.1.1.

Cykl 'ycia '#dania w Spring MVC ............................................................................. 190

7.1.2.

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 g0ównej ................................................................... 195

7.2.3.

Produkowanie widoków .............................................................................................. 198

7.2.4.

Definiowanie widoku strony g0ó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 przesy0anych 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 wysy0anych na serwer ................................................................. 218

7.5.3.

Konfiguracja Springa do przesy0ania plików na serwer ............................................ 221

7.6. Podsumowanie ............................................................................................................................ 221

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

8

Spis tre%ci

Rozdzia% 8. Praca ze Spring Web Flow

223

8.1. Instalacja Spring Web Flow ..................................................................................................... 224

8.1.1.

Konfiguracja Spring Web Flow .................................................................................. 224

8.2. Sk%adowe przep%ywu .................................................................................................................. 227

8.2.1.

Stany ............................................................................................................................ 227

8.2.2.

Przej(cia ....................................................................................................................... 230

8.2.3.

Dane przep0ywu .......................................................................................................... 231

8.3. ,'czymy wszystko w ca%o(-: zamówienie pizzy ...................................................................... 233

8.3.1.

Definiowanie bazowego przep0ywu ........................................................................... 233

8.3.2.

Zbieranie informacji o kliencie ................................................................................... 237

8.3.3.

Budowa zamówienia ................................................................................................... 242

8.3.4.

Przyjmowanie p0atno(ci .............................................................................................. 245

8.4. Zabezpieczanie przep%ywu ........................................................................................................ 247
8.5. Podsumowanie ............................................................................................................................ 247

Rozdzia% 9. Zabezpieczanie Springa

249

9.1. Wprowadzenie do Spring Security .......................................................................................... 250

9.1.1.

Rozpoczynamy prac, ze Spring Security ................................................................... 250

9.1.2.

Konfiguracyjna przestrze8 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 bezpiecze8stwa sieciowego ................................................ 253

9.2.3.

Przechwytywanie '#da8 .............................................................................................. 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.

W0#czenie funkcji „pami,taj mnie” ............................................................................ 269

9.5. Zabezpieczanie metod ............................................................................................................... 270

9.5.1.

Zabezpieczanie metod z adnotacj# @Secured .......................................................... 270

9.5.2.

Adnotacja @RolesAllowed ze specyfikacji JSR-250 ................................................. 271

9.5.3.

Zabezpieczenia przed wykonaniem metody ze SpEL i po jej wykonaniu .............. 271

9.5.4.

Deklaracja przeci,< bezpiecze8stwa na poziomie metody ....................................... 276

9.6. Podsumowanie ............................................................................................................................ 276

C

Z !#

3. I

NTEGRACJA W

S

PRINGU

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 us0ugi RMI ........................................................................................ 283
10.2.2. Dowi#zanie us0ugi 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 us0ug Hessian/Burlap ................................................................................ 290

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Spis tre%ci

9

10.4. Obiekt HttpInvoker ................................................................................................................... 292

10.4.1. Udost,pnianie komponentów jako us0ug HTTP ....................................................... 292
10.4.2. Dost,p do us0ug przez HTTP ..................................................................................... 293

10.5. Publikacja i konsumpcja us%ug sieciowych .............................................................................. 294

10.5.1. Tworzenie punktów ko8cowych JAX-WS w Springu ............................................... 295
10.5.2. Po(rednik us0ug JAX-WS po stronie klienta .............................................................. 299

10.6. Podsumowanie ............................................................................................................................ 300

Rozdzia% 11. Spring i model REST

301

11.1. Zrozumienie REST .................................................................................................................... 302

11.1.1. Fundamenty REST ..................................................................................................... 302
11.1.2. Obs0uga 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. Obs0uga 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. Wysy0anie 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

Rozdzia% 12. Obs%uga komunikatów w Springu

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 po0#cze8 ........................................................................................ 339
12.2.2. Deklaracja miejsca docelowego komunikatów ActiveMQ ........................................ 340

12.3. Szablon JMS Springa ................................................................................................................. 340

12.3.1. Kod JMS a obs0uga 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

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

10

Spis tre%ci

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 powiadomie8 ........................................................................................... 371

13.4. Podsumowanie ............................................................................................................................ 372

Rozdzia% 14. Pozosta%e zagadnienia

373

14.1. Wyodr&bnianie konfiguracji ..................................................................................................... 374

14.1.1. Zast,powanie symboli zast,pczych we w0a(ciwo(ciach ............................................ 374
14.1.2.

Nadpisywanie w0a(ciwo(ci ......................................................................................... 377

14.1.3. Szyfrowanie zewn,trznych w0a(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 wysy0aj#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

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Aspektowy Spring

W tym rozdziale omówimy:

Podstawy programowania aspektowego

Tworzenie aspektów z POJO

Stosowanie adnotacji @AspectJ

Wstrzykiwanie zale'no(ci do aspektów AspectJ

Gdy pisz, ten rozdzia0, 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 zap0aci<. Niewiele mo'emy zrobi< w celu unikni,cia wydatków na
to, by mieszka< w ch0odnych 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 zak0ad energetyczny
dok0adnie wiedzia0, jaki wystawi< nam rachunek.

Teraz wyobraXmy sobie, co by si, sta0o, gdyby taki licznik znikn#0 i nikt nie przy-

chodzi0, by sprawdzi< nasze zu'ycie energii elektrycznej. Za0ó'my, 'e do ka'dego
w0a(ciciela domu nale'a0oby skontaktowanie si, z zak0adem energetycznym i zg0osze-
nie swojego zu'ycia energii. Cho< jest mo'liwe, 'e jaki( obsesyjny w0a(ciciel domu
uwa'nie rejestrowa0by ka'de u'ycie (wiat0a, telewizji czy klimatyzacji, wi,kszo(< by
si, tym nie przejmowa0a. Wi,kszo(< poda0aby swoje przybli'one zu'ycie, a niektórzy nie
zg0osiliby zu'ycia w ogóle. Sprawdzanie zu'ycia energii by0oby k0opotliwe, a pokusa, by
nie zap0aci<, mog0aby okaza< si, zbyt silna.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

108

R

OZDZIA'

4.

Aspektowy Spring

Ta forma systemu p0atno(ci za energi, elektryczn# móg0aby by< (wietna dla klientów,

lecz by0aby daleka od idea0u z punktu widzenia zak0adów energetycznych. To dlatego
wszyscy mamy w domu liczniki energii i dlatego raz w miesi#cu kto( zagl#da, by odczyta<
licznik i poinformowa< zak0ad 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 by0oby niewygodne, gdyby(my musieli wywo0ywa< 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 w0a(cicieli domów. Koszenie trawników, odku-
rzanie dywanów czy sprz#tanie 0azienki to czynno(ci, w które posiadacz domu jest
aktywnie zaanga'owany. Natomiast kontrola zu'ycia elektryczno(ci w domu jest z punktu
widzenia w0a(ciciela domu czynno(ci# pasywn# (cho< by0oby cudownie, gdyby kosze-
nie trawników te' by0o czynno(ci# pasywn# — zw0aszcza w takie gor#ce dni).

W oprogramowaniu niektóre czynno(ci s# powszechne w wi,kszo(ci aplikacji. Reje-

strowanie transakcji, ich bezpiecze8stwo 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 by0o, aby obiekty naszej aplikacji pozosta0y skoncentrowane na problemach
z dziedziny biznesowej, do jakich zosta0y zaprojektowane, i pozostawi0y pewne aspekty
do obs0ugi 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 zagadnie8 przecinaj#cych od logiki biznesowej jest
miejscem, gdzie do pracy w0#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 przyk0adem 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 zastosowa8 aspektów, w tym transakcje deklara-
cyjne, bezpiecze8stwo oraz pami,< podr,czn#.

W tym rozdziale zostanie omówiona obs0uga aspektów w Springu, w tym sposób

deklarowania zwyk0ych klas, aby sta0y 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 uzupe0ni< dzia0anie (ro-
dowiska AOP Springa. Lecz najpierw, zanim si, zajmiemy transakcjami, bezpiecze8-
stwem i pami,ci# podr,czn#, dowiedzmy si,, w jaki sposób aspekty s# implementowane
w Springu, zaczynaj#c od paru zupe0nych podstaw AOP.

4.1.

Czym jest programowanie aspektowe

Jak wcze(niej wspomnieli(my, aspekty pomagaj# zamyka< w modu0ach zagadnienia
przecinaj#ce. W skrócie, zagadnienie przecinaj#ce mo'na opisa< jako dowolny mecha-
nizm, którego wp0yw jest u'ywany na wielu miejscach w aplikacji. Bezpiecze8stwo na

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.1.

Czym jest programowanie aspektowe

109

przyk0ad jest zagadnieniem przecinaj#cym, w tym sensie, 'e wiele metod w aplikacji
mo'e podlega< stosowaniu regu0 bezpiecze8stwa. Na rysunku 4.1 pokazano obrazow#
ilustracj, zagadnie8 przecinaj#cych.

Rysunek 4.1.

Aspekty zamykaj4

w modu5ach zagadnienia przecinaj4ce,
które dotycz4 logiki zawartej w wielu
spo:ród obiektów aplikacji

Na rysunku 4.1 pokazano typow# aplikacj,, która jest podzielona na modu0y. G0ównym
zadaniem ka'dego z modu0ów jest realizowanie us0ug ze swojej szczególnej dziedziny.
Lecz ka'dy modu0 potrzebuje tak'e podobnych mechanizmów pomocniczych, takich
jak bezpiecze8stwo 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 ca0ej aplikacji.
Z kolei stosowanie delegacji bywa uci#'liwe, poniewa' mo'e by< potrzebne skompli-
kowane wywo0anie 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 modu0ach 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 ca0ym kodzie. Po drugie, nasze modu0y
us0ugowe b,d# teraz bardziej uporz#dkowane, poniewa' zawieraj# jedynie kod dotycz#cy
ich g0ównego zadania (albo podstawowych funkcji), za( zagadnienia drugorz,dne zosta0y
przeniesione do aspektów.

4.1.1.

Definiujemy terminologi6 dotycz7c7 AOP

Podobnie jak w przypadku innych technologii, wraz z rozwojem AOP powsta0 specyficzny
'argon opisuj#cy t, technik, programistyczn#. Aspekty s# cz,sto opisywane za pomoc#
poj,< takich jak „porada”, „punkt przeci,cia” czy „punkt z0#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<.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

110

R

OZDZIA'

4.

Aspektowy Spring

Rysunek 4.2.

Funkcjonalno:> aspektu

(porada) jest wplatana do wykonania
programu w jednym lub wiAcej punktach
z54czenia

P

ORADA

Gdy osoba odczytuj#ca licznik poka'e si,
w naszym domu, jej zadaniem jest po-
informowanie zak0adu energetycznego
o wskazywanej liczbie kilowatogodzin.
Z pewno(ci# osoba ta ma list, domów,
które musi odwiedzi<, za( informacje,
które dostarcza zak0adowi energetyczne-
mu, s# wa'ne. Lecz g0ównym zadaniem
osoby odczytuj#cej liczniki jest sama
czynno(< notowania zu'ycia energii.

Podobnie, aspekty maj# g0ówne zada-

nie — czynno(<, której wykonanie jest
celem ich istnienia. W terminologii pro-
gramowania aspektowego zadanie aspektu
jest nazywane porad'.

Porada jest dla aspektu definicj# zarówno czynno(ci, która ma zosta< wykonana, jak

i w0a(ciwego momentu jej wykonania. Czy aspekt powinien by< wykonany przed wywo-
0aniem metody? Po jej wykonaniu? Zarówno przed wywo0aniem metody, jak i po niej?
A mo'e tylko wtedy, gdy metoda zg0osi wyj#tek? Aspekty w Springu mog# dzia0a< z pi,-
cioma rodzajami porad:

Before

— Funkcjonalno(< porady jest wykonywana przed wywo0aniem metody

z porad#.

After

— Funkcjonalno(< porady jest wykonywana po zako8czeniu dzia0ania

metody z porad#, niezale'nie od wyniku jej dzia0ania.

After-returning

— Funkcjonalno(< porady jest wykonywana po prawid0owym

zako8czeniu metody z porad#.

After-throwing

— Funkcjonalno(< porady jest wykonywana po zg0oszeniu

wyj#tku przez metod, z porad#.

Around

— Porada realizuje t, sam# funkcjonalno(< zarówno przed wywo0aniem,

jak i po zako8czeniu metody z porad#.

P

UNKTY Z'GCZENIA

Zak0ad energetyczny obs0uguje wiele domów, prawdopodobnie wr,cz ca0e 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 mog0aby
odczytywa< wiele ró'nych przyrz#dów pomiarowych, lecz w ramach swoich obowi#zków
s0u'bowych powinna przyj#< za cel w0a(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 z0#czenia jest
tak# pozycj# w przebiegu wykonania programu, w której mo'e zosta< wpi,ty aspekt.
Takim punktem mo'e by< wywo0anie metody, zg0oszenie wyj#tku czy nawet modyfi-
kacja zawarto(ci pola. S# to pozycje, w których kod aspektu mo'e zosta< w0#czony
w normalny przebieg dzia0ania naszej aplikacji, wzbogacaj#c tym jej dzia0anie.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.1.

Czym jest programowanie aspektowe

111

P

UNKTY PRZECIJCIA

Nie jest mo'liwe, by jedna osoba odczytuj#ca liczniki zdo0a0a odwiedzi< wszystkie domy,
którym elektryczno(< dostarcza ten sam zak0ad energetyczny. Pojedynczej osobie jest
przypisany jedynie pewien podzbiór wszystkich domów. Podobnie porada nie musi
koniecznie do0#cza< aspektu do ka'dego punktu z0#czenia w aplikacji. Punkty przeci&cia
pozwalaj# zaw,zi< list, punktów z0#czenia, do których zastosowany b,dzie aspekt.

Je(li porada definiowa0a 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 z0#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'e8 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 dzia0ania, na przyk0ad na podstawie warto(ci parametrów metod.

A

SPEKTY

Gdy osoba odczytuj#ca liczniki rozpoczyna dzie8 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.

W

PROWADZENIA

Wprowadzenie pozwala nam dodawa< nowe metody lub atrybuty do istniej#cych klas.
Na przyk0ad mo'emy skonstruowa< klas, z porad#, o nazwie

Auditable

. B,dzie ona

przechowywa0a informacj, o momencie ostatniej modyfikacji obiektu. Mo'e to by< klasa
tak prosta, 'e b,dzie posiada0a tylko jedn# metod,, nazwan#

setLastModified(Date)

i zmienn# o zasi,gu instancji, która b,dzie przechowywa0a 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 dzia0anie i zmienn# stanu.

W

PLATANIE

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 z0#czenia. Wplatanie mo'e mie< miejsce w ró'nych momen-
tach cyklu 'ycia docelowego obiektu:

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.

W czasie )adowania klasy

— Aspekty zostaj# wplecione, gdy klasa docelowa

jest 0adowana do maszyny wirtualnej Javy (JVM). W tym celu potrzebny jest
specjalny

ClassLoader

, który rozszerza kod bajtowy docelowej klasy, zanim

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

112

R

OZDZIA'

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.

W czasie dzia)ania

— Aspekty zostaj# wplecione w jakim( momencie podczas

dzia0ania aplikacji. W typowej sytuacji kontener aspektowy b,dzie dynamicznie
generowa0 obiekt po(rednicz#cy, który zostanie po0#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< w0#czone
do obiektów aplikacji. Punktami z0#czenia s# wszystkie punkty w przebiegu dzia0ania
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 z0#-
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
zosta0y 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 z0#cze8 posiadaj#. Niektóre pozwalaj# stosowa< porady na
poziomie modyfikacji pól, podczas gdy inne udost,pniaj# jedynie punkty z0#cze8 zwi#zane
z wywo0aniem 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 z0#czenia, w których powinny zosta< wplecione aspekty, jest tym, co
stanowi aspektowy framework.

Wiele si, zmieni0o w bran'y frameworków aspektowych przez ostatnie kilka lat.

Zosta0y poczynione porz#dki, w wyniku których niektóre spo(ród frameworków zosta0y
po0#czone ze sob#, z kolei inne zaczynaj# zanika<. W roku 2005 projekt AspectWerkz
zosta0 po0#czony z AspectJ, co by0o ostatni# istotn# zmian# w (wiecie AOP, pozosta-
wiaj#c nam do wyboru trzy dominuj#ce frameworki aspektowe:

AspectJ (http://eclipse.org/aspectj),

JBoss AOP (http://www.jboss.org/jbossaop),

Spring AOP (http://www.springframework.org).

Poniewa' ksi#'ka ta jest po(wi,cona frameworkowi Spring, skupimy si, na Spring AOP.
Mimo to wyst,puje wiele podobie8stw mi,dzy projektami Spring i AspectJ, za( obs0uga
AOP w Springu zawiera wiele zapo'ycze8 z projektu AspectJ.

Obs0uga AOP w Springu ma cztery odmiany:

Klasyczna obs0uga AOP w Springu na bazie obiektów po(rednicz#cych.

Aspekty sterowane adnotacj# @AspectJ.

Aspekty zbudowane z „czystych” POJO.

Wstrzykiwane aspekty z AspektJ (dost,pne we wszystkich wersjach Springa).

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.1.

Czym jest programowanie aspektowe

113

Pierwsze trzy pozycje s# w0a(ciwie odmianami obs0ugi AOP przez Springa na bazie
obiektów po(rednicz#cych. W efekcie obs0uga AOP w Springu jest ograniczona do prze-
chwytywania metod. Je(li potrzebujemy w Springu rozszerzonego przechwytywania
prostych metod (na przyk0ad przechwytywania konstruktora albo w0a(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 b6dzie omówienia klasycznego AOP w Springu?

S*owo klasyczne zwykle budzi pozytywne skojarzenia. Klasyczne samochody, klasyczny
turniej golfowy czy te' klasyczna Coca-Cola — wszystkie s1 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 istniej1
w Springu znacznie bardziej uporz1dkowane 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 oci3'a*ego i nadmiernie skom-
plikowanego. Bezpo(rednie wykorzystanie ProxyFactoryBean mo'e by5 m3cz1ce.

Zatem zdecydowa*em, 'e do bie'1cego wydania tej ksi1'ki nie w*1cz3 w ogóle omó-
wienia klasycznego AOP w Springu. Je(li naprawd3 ciekawi ci3, Czytelniku, jak dzia*a
ten model AOP, mo'esz sprawdzi5 w pierwszych dwóch wydaniach. Lecz s1dz3, 'e prze-
konasz si3, 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 zagadnie8
w aspektowym frameworku Spring.

P

ORADA

S

PRINGA JEST ZAPISANA W

J

AVIE

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 dzie8
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 sk0adnia konfiguracji b,d# naturalne dla programistów Javy.

Inaczej jest w AspectJ. Cho< obecnie AspectJ obs0uguje ju' aspekty oparte na ad-

notacjach, AspectJ pojawi0 si, tak'e jako rozszerzenie j,zyka Java. Takie podej(cie ma
zarówno zalety, jak i wady. Posiadanie specjalizowanego j,zyka do obs0ugi 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 sk0adni.

S

PRING DO'GCZA 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 wywo0ania metod z porad# i przekiero-
wuje wywo0ania tych metod do komponentu docelowego.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

114

R

OZDZIA'

4.

Aspektowy Spring

Rysunek 4.3.

Aspekty w Springu zosta5y zaimplementowane

jako obiekty po:rednicz4ce, które opakowuj4 obiekt docelowy.
Obiekt po:rednicz4cy przechwytuje wywo5ania metod, wykonuje
dodatkow4 logikA aspektu, a nastApnie wywo5uje metodA
docelow4

W czasie pomi,dzy przechwyceniem przez obiekt po(rednicz#cy wywo0ania metody
a momentem wywo0ania metody komponentu docelowego obiekt po(rednicz#cy reali-
zuje logik, aspektu.

Spring nie tworzy obiektu z po(rednikiem, dopóki aplikacja nie b,dzie potrzebowa0a

okre(lonego komponentu. Je(li korzystamy z

ApplicationContext

, obiekt z po(redni-

kiem zostanie utworzony, gdy kontekst b,dzie 0adowa0 wszystkie nale'#ce do niego
komponenty z

BeanFactory

. Poniewa' Spring tworzy obiekty po(rednicz#ce w czasie

dzia0ania, korzystanie z AOP w Springu nie zmusza nas do stosowania specjalnego kom-
pilatora, który umo'liwia0by wplatanie aspektów.

S

PRING OBS'UGUJE JEDYNIE PUNKTY Z'GCZENIA ZWIGZANE Z METODAMI

Jak wspomnieli(my wcze(niej, w poszczególnych implementacjach AOP stosowane s#
ró'ne modele punktów z0#czenia. Poniewa' Spring bazuje na dynamicznych obiektach
po(rednicz#cych, obs0uguje tylko punkty z0#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 z0#czenia zwi#zanymi z metodami oferuj# tak'e obs0ug, punktów
z0#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 wywo0a8 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 wywo0a8 metod, b,dziemy mogli uzupe0ni< funkcjonalno(< AOP w Springu za
pomoc# AspectJ.

Teraz mamy ju' ogólne poj,cie, do czego s0u'y programowanie aspektowe i w jaki

sposób jest obs0ugiwane przez Springa. Nadszed0 czas, by zakasa< r,kawy i wzi#< si, za
tworzenie aspektów w Springu. Zacznijmy od deklaracyjnego modelu AOP w Springu.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.2.

Wybieramy punkty z2#czenia za pomoc# punktów przeci"cia

115

4.2.

Wybieramy punkty z<7czenia
za pomoc7 punktów przeci6cia

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 sk0adniki 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'e8 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 by0 dla nas framewor-
kiem nowym, ten podrozdzia0 mo'e s0u'y< jako szybki samouczek pisania punktów
przeci,cia w stylu AspectJ. Poszukuj#cym bardziej szczegó0owego omówienia frame-
worka AspectJ oraz pochodz#cego z tego frameworka j,zyka wyra'e8 punktów prze-
ci,cia z ca0ego serca polecam drugie wydanie ksi#'ki AspectJ in Action, któr# napisa0
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 obs0ugi-
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# obs0ugiwane przez
Spring AOP.

Tabela 4.1.

Spring do definiowania aspektów wykorzystuje jAzyk wyraWeX punktów

przeciAcia pochodz4cy z AspectJ

Desygnator
w stylu AspectJ

Opis

args()

Ogranicza dopasowanie punktów z*1czenia do wywo*a6 metod, których
argumenty s1 instancjami okre(lonych typów.

@args()

Ogranicza dopasowanie punktów z*1czenia do wywo*a6 metod, których
argumenty s1 opatrzone adnotacjami okre(lonych typów.

execution()

Dopasowuje punkty z*1czenia, które s1 wywo*aniami metod.

this()

Ogranicza dopasowanie punktów z*1czenia do takich, które posiadaj1
w obiekcie po(rednicz1cym AOP referencj3 do beana okre(lonego typu.

target()

Ogranicza dopasowanie punktów z*1czenia do takich, w których obiekt
docelowy jest instancj1 okre(lonego typu.

@target()

Ogranicza dopasowanie do punktów z*1czenia, w których klasa wywo*ywanego
obiektu jest opatrzona adnotacj1 okre(lonego typu.

within()

Ogranicza dopasowanie do punktów z*1czenia b3d1cych instancjami
okre(lonych typów.

@within()

Ogranicza dopasowanie do punktów z*1czenia b3d1cych instancjami typów,
które s1 opatrzone okre(lon1 adnotacj1 (w zastosowaniu dla Spring AOP
wywo*ania metod zadeklarowanych w typach opatrzonych okre(lon1
adnotacj1).

@annotation

Ogranicza dopasowanie punktów z*1czenia do takich, w których obiekt b3d1cy
przedmiotem dzia*ania punktów z*1czenia jest opatrzony okre(lon1 adnotacj1.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

116

R

OZDZIA'

4.

Aspektowy Spring

Próba u'ycia którego( z desygnatorów pochodz#cych z AspectJ, niewymienionego

w powy'szej tabeli, b,dzie skutkowa0a zg0oszeniem wyj#tku

IllegalArgumentException

.

Przegl#daj#c list, obs0ugiwanych desygnatorów, zwró<my uwag,, 'e

execution

jest

jedynym desygnatorem, który faktycznie realizuje dopasowanie. Wszystkich pozosta0ych
u'ywamy do ograniczania takich dopasowa8. To znaczy, 'e podstawowy jest desygnator

execution

, którego u'yjemy w ka'dej definicji punktu przeci,cia, jak# napiszemy. Pozo-

sta0ych b,dziemy u'ywa< do ograniczania zasi,gu punktu przeci,cia.

4.2.1.

Piszemy definicje punktów przeci6cia

Przyk0adowo mo'emy u'y< wyra'enia pokazanego na rysunku 4.4, by zastosowa< porad,
za ka'dym wywo0aniem metody

play()

, nale'#cej do klasy

Instrument

.

Rysunek 4.4.

Wybieramy metodA play(), zdefiniowan4 w klasie Instrument,

za pomoc4 wyraWenia punktu przeciAcia 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
pe0n#, 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 za0ó'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 zasiAg punktu przeciAcia za pomoc4

desygnatora within()

Zauwa'my, 'e u'yli(my operatora

&&

, by po0#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 dzia0ania desygnatora.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

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 dzia0anie punktu przeci,cia do tego konkretnego komponentu.

Przyk0adowo, 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 wywo0a8 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 korzysta0y.

4.3.

Deklarujemy aspekty w j6zyku 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 stara8 znalaz0 si, w przestrzeni nazw

aop

Springa.

Zestawienie elementów konfiguracyjnych AOP umieszczono w tabeli 4.2.

W rozdziale 2., pokazuj#c przyk0ad wstrzykiwania zale'no(ci, zorganizowali(my

turniej talentów o nazwie Idol Springa. W przyk0adzie tym utworzyli(my powi#zania
dla kilku wykonawców, jako elementów

<bean>

, umo'liwiaj#c im zademonstrowanie ich

uzdolnie8. To wszystko by0o wspania0# rozrywk#. Lecz tego rodzaju przedsi,wzi,cie
potrzebuje widowni albo b,dzie bezcelowe.

Zatem, aby zilustrowa< dzia0anie 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" />

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

118

R

OZDZIA'

4.

Aspektowy Spring

Tabela 4.2.

Elementy konfiguracyjne Spring AOP upraszczaj4 deklaracjA aspektów

bazuj4cych na POJO

Element konfiguracji AOP

Zastosowanie

<aop:advisor>

Definiuje doradc3 aspektowego.

<aop:after>

Definiuje aspektow1 porad3 after (niezale'n1 od wyniku
dzia*ania metody zaopatrzonej w porad3).

<aop:after-returning>

Definiuje aspektow1 porad3 after-returning (po pomy(lnym
zako6czeniu dzia*ania metody).

<aop:after-throwing>

Definiuje aspektow1 porad3 after-throwing (po zg*oszeniu
wyj1tku przez metod3).

<aop:around>

Definiuje aspektow1 porad3 around (zarówno przed
wykonaniem metody, jak i po zako6czeniu jej dzia*ania).

<aop:aspect>

Definiuje aspekt.

<aop:aspect-autoproxy>

Prze*1cza w tryb aspektów sterowanych adnotacjami z u'yciem
@AspectJ.

<aop:before>

Definiuje aspektow1 porad3 before (przed wykonaniem
metody).

<aop:config>

Element nadrz3dnego poziomu w konfiguracji aspektowej.
Wi3kszo(5 elementów

<aop:*>

powinna znajdowa5 si3

wewn1trz elementu

<aop:config>

.

<aop:declare-parents>

Wprowadza do obiektów z porad1 dodatkowe interfejsy,
implementowane w przezroczysty sposób.

<aop:pointcut>

Definiuje punkt przeci3cia.

Listing 4.1. Klasa Audience dla naszego turnieju talentów

package com.springinaction.springidol;
public class Audience {
public void takeSeats() {

Przed wystApem

System.out.println("Widzowie zajmujM miejsca.");
}

public void turnOffCellPhones() {

Przed wystApem

System.out.println("Widzowie wyQMczajM telefony komórkowe.");
}

public void applaud() {

Po wystApie

System.out.println("Brawooo! Oklaski!");
}

public void demandRefund() {

Po nieudanym wystApie

System.out.println("Buu! Oddajcie pieniMdze za bilety!");
}
}

Mimo skromnego wygl#du klasy

Audience

niezwyk0e w niej jest to, 'e ma ona wszystko,

czego potrzeba do utworzenia aspektu. Potrzebuje ona jedynie odrobiny specjalnych
aspektowych czarów Springa.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.3.

Deklarujemy aspekty w j"zyku XML

119

4.3.1.

Deklarujemy porady before i after

Korzystaj#c z elementów konfiguracyjnych Spring AOP, jak pokazano na listingu 4.2,
mo'emy z komponentu

audience

utworzy< aspekt.

Listing 4.2. Definiujemy aspekt audience, korzystaj4c z elementów
konfiguracyjnych Spring AOP

<aop:config>
<aop:aspect ref="audience">

Referencja do komponentu audience

<aop:before pointcut=
"execution(* com.springinaction.springidol.Performer.perform(..))"
method="takeSeats" />

Przed wystApem

<aop:before pointcut=
"execution(* com.springinaction.springidol.Performer.perform(..))"
method="turnOffCellPhones" />

Przed wystApem

<aop:after-returning pointcut=
"execution(* com.springinaction.springidol.Performer.perform(..))"
method="applaud" />

Po wystApie

<aop:after-throwing pointcut=
"execution(* com.springinaction.springidol.Performer.perform(..))"
method="demandRefund" />

Po nieudanym wystApie

</aop:aspect>
</aop:config>

Pierwszym, co zauwa'amy w temacie elementów konfiguracyjnych Spring AOP, jest fakt,
'e prawie wszystkie z nich powinny by< u'yte wewn#trz kontekstu elementu

<aop:

config>

. Jest od tej regu0y kilka wyj#tków, lecz podczas deklarowania komponentów

jako aspektów zawsze zaczynamy od elementu

<aop:config>

.

Wewn#trz elementu

<aop:config>

mo'emy zadeklarowa< jeden albo wi,cej aspektów,

doradców lub punktów przeci,cia. Na listingu 4.2 za pomoc# elementu

<aop:aspect>

zadeklarowali(my pojedynczy punkt przeci,cia. Atrybut

ref

zawiera referencj, do kom-

ponentu w postaci POJO, który b,dzie u'yty jako dostawca funkcjonalno(ci aspektu —
w tym wypadku jest to komponent

audience

. Komponent, do którego referencj, zawiera

atrybut

ref

, b,dzie dostarcza0 metody wywo0ywane przez ka'd# z porad w aspekcie.

Aspekt posiada cztery ró'ne porady. Dwa elementy

<aop:before>

definiuj# porady

realizowane przed wykonaniem metody

, które wywo0aj# metody

takeSeats()

oraz

turn

OffCellPhones()

(zadeklarowane z u'yciem atrybutu

method

) komponentu

Audience

,

przed wykonaniem jakiejkolwiek metody dopasowanej do punktu przeci,cia. Element

<aop:after-returning>

definiuje porad/ realizowan0 po powrocie z metody, która wywo0a

metod,

applaud()

po punkcie przeci,cia. Jednocze(nie element

<aop:after-throwing>

definiuje porad/ realizowan0 po zg)oszeniu wyj0tku, która wywo0a metod,

demandRe

fund()

, je(li zostanie zg0oszony jaki( wyj#tek. Na rysunku 4.6 pokazano, jak logika

porady jest wplatana mi,dzy logik, biznesow#.

We wszystkich elementach porad atrybut

pointcut

definiuje punkt przeci,cia, w któ-

rym zostanie zastosowana porada. Warto(<, jak# podamy w atrybucie

pointcut

, jest punk-

tem przeci,cia zdefiniowanym w sk0adni wyra'e8 punktów przeci,cia w stylu AspectJ.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

120

R

OZDZIA'

4.

Aspektowy Spring

Rysunek 4.6.

Aspekt Audience zawiera cztery porady, wplataj4ce swoj4 logikA wokó5

metod, które zostan4 dopasowane do punktu przeciAcia

Zapewne zwróci nasz# uwag, fakt, 'e wszystkie elementy porad posiadaj# tak# sam#
warto(< atrybutu

pointcut

. To dlatego, 'e wszystkie porady maj# zosta< zastosowane

w tym samym punkcie przeci,cia. Widzimy tu z0amanie regu0y „nie powtarzaj si,”
(ang. don’t repeat yourself, DRY). Je(li póXniej postanowiliby(my zmieni< punkt prze-
ci,cia, musieliby(my dokona< modyfikacji w czterech ró'nych miejscach.

Aby unikn#< duplikatów w definicji punktów przeci,cia, mo'emy si, zdecydowa< na

zdefiniowanie nazwanego punktu przeci,cia za pomoc# elementu

<aop:pointcut>

. Kod

z listingu 4.3 demonstruje sposób u'ycia elementu

<aop:pointcut>

wraz z elementem

<aop:aspect>

do zdefiniowania nazwanego punktu przeci,cia, którego b,dziemy mogli

u'y< we wszystkich elementach porad.

Listing 4.3. Definiujemy nazwany punkt przeciAcia, by wyeliminowa> nadmiarowe
definicje punktów przeciAcia

<aop:config>
<aop:aspect ref="audience">
<aop:pointcut id="performance" expression=
"execution(* com.springinaction.springidol.Performer.perform(..))"
/>

<aop:before
pointcut-ref="performance"
method="takeSeats" />
<aop:before
pointcut-ref="performance"
method="turnOffCellPhones" />
<aop:after-returning

Referencje

pointcut-ref="performance"

do punktu przeciAcia

method="applaud" />
<aop:after-throwing
pointcut-ref="performance"
method="demandRefund" />

Definicja
punktu przeciAcia

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.3.

Deklarujemy aspekty w j"zyku XML

121

</aop:aspect>
</aop:config>

Teraz punkt przeci,cia jest zdefiniowany w jednym miejscu, do którego odwo0uje si,
wiele elementów porad. Element

<aop:pointcut>

definiuje punkt przeci,cia o nazwie

performance

. Jednocze(nie wszystkie elementy porad zosta0y zmienione na odwo0ania do

nazwanego punktu przeci,cia za pomoc# atrybutu

pointcut-ref

.

Jak pokazano na listingu 4.3, element

<aop:pointcut>

definiuje punkt przeci,cia,

do którego mog# si, odwo0ywa< wszystkie porady wewn#trz tego samego elementu

<aop:aspect>

. Lecz mo'emy tak'e zdefiniowa< punkty przeci,cia, które b,d# widoczne

z wielu aspektów. W tym celu musieliby(my umie(ci< element

<aop:pointcut>

bezpo-

(rednio wewn#trz elementu

<aop:config>

.

4.3.2.

Deklarujemy porad6 around

Obecna implementacja aspektu

Audience

dzia0a rewelacyjnie, lecz podstawowe pora-

dy

before

i

after

maj# pewne ograniczenia. W szczególno(ci du'ym wyzwaniem jest

wymiana informacji mi,dzy par# porad

before

i

after

bez uciekania si, do przechowy-

wania tej informacji w zmiennych sk0adowych.

Przyk0adowo, wyobraXmy sobie, 'e poza wy0#czeniem telefonów komórkowych i okla-

skiwaniem wykonawców po zako8czeniu, chcieliby(my, by widzowie zerkn,li na zegarki
i poinformowali nas o czasie trwania danego wyst,pu. Jedynym sposobem osi#gni,cia
tego za pomoc# porad

before

i

after

jest zanotowanie momentu rozpocz,cia w pora-

dzie

before

i raportowanie czasu trwania w jakiej( poradzie

after

. Lecz musieliby(my

przechowa< moment rozpocz,cia w zmiennej sk0adowej. Poniewa' za( komponent

Audience

jest instancj# klasy singletonowej, nie by0oby to rozwi#zaniem bezpiecznym

ze wzgl,du na prac, wielow#tkow#, gdyby(my w taki sposób przechowywali informacj,
o stanie.

Pod tym wzgl,dem porada

around

ma przewag, nad par# porad

before

i

after

. Za

pomoc# porady

around

mo'emy osi#gn#< ten sam efekt, co za pomoc# osobnych porad

before

i

after

, lecz wykonuj#c wszystkie czynno(ci za pomoc# jednej metody. Dzi,ki

umieszczeniu w jednej metodzie ca0ego zbioru porad nie ma potrzeby przechowywania
informacji o stanie w zmiennej sk0adowej.

Przyk0adowo rozwa'my now# metod,

watchPerformance()

, zdefiniowan# na lis-

tingu 4.4.

Listing 4.4. Metoda watchPerformance() realizuje funkcjonalno:> aspektowej
porady around

public void watchPerformance(ProceedingJoinPoint joinpoint) {
try {
System.out.println("Widzowie zajmujM miejsca.");
System.out.println("Widzowie wyQMczajM telefony komórkowe.");
long start = System.currentTimeMillis();

Przed wystApem

joinpoint.proceed();

Przej:cie do metody opatrzonej porad4

long end = System.currentTimeMillis();

Po wystApie

System.out.println("Brawooo! Oklaski!");
System.out.println("WystUp trwaQ " + (end - start)
+ " miliskund.");

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

122

R

OZDZIA'

4.

Aspektowy Spring

} catch (Throwable t) {
System.out.println("Buu! Oddajcie pieniMdze za bilety!");
}
}

Pierwszym, co zauwa'amy w tej nowej metodzie porady, jest fakt, 'e otrzymuje ona
parametr

ProceedingJoinPoint

. Obiekt ten jest konieczny, aby(my byli w stanie wywo0a<

docelow# metod, z wn,trza naszej porady. Metoda porady wykonuje wszystkie swoje
zadania, po czym, gdy jest gotowa do przekazania sterowania do metody docelowej, wy-
wo0a metod,

proceed()

obiektu

ProceedingJoinPoint

.

Zwró<my uwag,, 'e spraw# krytyczn# jest, aby(my pami,tali o umieszczeniu w pora-

dzie wywo0ania metody

proceed()

. Gdyby(my o tym szczególe zapomnieli, w efekcie

nasza porada blokowa0aby dost,p do metody docelowej. Mo'e by0by to efekt zgodny
z naszymi zamierzeniami, lecz jest znacznie bardziej prawdopodobne, 'e naprawd,
chcieliby(my, aby metoda docelowa zosta0a w jakim( momencie wywo0ana.

Jeszcze jedn# interesuj#c# informacj# jest fakt, 'e podobnie jak istnieje mo'liwo(<

zablokowania dost,pu do metody docelowej przez pomini,cie wywo0ania metody

pro

ceed()

, mo'emy tak'e umie(ci< w poradzie wielokrotne wywo0anie tej metody.

Jednym z powodów, by tak post#pi<, mo'e by< implementowanie logiki ponawiania
próby wykonania pewnej czynno(ci w sytuacji, gdy realizuj#ca j# metoda docelowa
zako8czy0a si, niepowodzeniem.

W przypadku aspektu

audience

metoda

watchPerformance()

zawiera ca0# funkcjo-

nalno(< wcze(niejszych czterech metod realizuj#cych porady, lecz tym razem zawar-
tych w jednej, w0#cznie z tym, 'e jest odpowiedzialna za obs0ug, zg0oszonych przez ni#
sam# wyj#tków. Zauwa'my te', 'e tu' przed wywo0aniem nale'#cej do punktu z0#czenia
metody

proceed()

w lokalnej zmiennej zostaje zapisany bie'#cy czas. Tu' po odzyska-

niu sterowania od wywo0anej metody wy(wietlany jest komunikat o czasie jej trwania.

Deklaracja porady

around

nie ró'ni si, znacz#co od deklaracji innych rodzajów porad.

Musimy jedynie pos0u'y< si, elementem

<aop:around>

, jak na listingu 4.5.

Listing 4.5. Definiujemy aspekt audience z uWyciem porady around

<aop:config>
<aop:aspect ref="audience">
<aop:pointcut id="performance2" expression=
"execution(* com.springinaction.springidol.Performer.perform(..))"
/>

<aop:around
pointcut-ref="performance2"
method="watchPerformance()" />

Deklaracja porady around

</aop:aspect>
</aop:config>

Podobnie jak w przypadku elementów XML dotycz#cych innych porad, element

<aop:

around>

otrzymuje punkt przeci,cia oraz nazw, metody realizuj#cej porad,. U'yli-

(my tu tego samego punktu przeci,cia co wcze(niej, lecz atrybutowi

method

nadali(my

warto(< wskazuj#c# na now# metod,

watchPerformance()

.

Po nieudanym
wystApie

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.3.

Deklarujemy aspekty w j"zyku XML

123

4.3.3.

Przekazujemy parametry do porady

Jak dot#d nasze aspekty mia0y prost# budow, i nie przyjmowa0y 'adnych parametrów.
Jedynym wyj#tkiem by0a metoda

watchPerformance()

, któr# napisali(my w celu realizo-

wania przyk0adowej porady

around

. Otrzymywa0a ona parametr

ProceedingJoinPoint

.

Poza tym jednym przypadkiem nie zajmowali(my naszym poradom uwagi kontrol# war-
to(ci parametrów przekazywanych do metody docelowej. By0o to jednak jak najbardziej
poprawne, poniewa' metoda

perform()

, dla której pisali(my porady, nie przyjmowa0a

parametrów.

Zdarzaj# si, jednak sytuacje, gdy mo'e si, okaza< po'yteczne, by porada nie tylko

opakowywa0a metod,, lecz tak'e kontrolowa0a warto(ci parametrów przekazywanych
do tej metody.

By si, przekona<, jak to dzia0a, wyobraXmy sobie nowy typ zawodnika w turnieju

talentów Idol Springa. Ten nowy zawodnik b,dzie wyst,powa0 z pokazami czytania
w my(lach i zostanie zdefiniowany za pomoc# interfejsu

MindReader

:

package com.springinaction.springidol;

public interface MindReader{
void interceptThoughts(String thoughts);

String getThoughts();
}

Interfejs

MindReader

zawiera definicje dwu podstawowych czynno(ci: przechwytywania

my(li ochotnika i informowania o ich tre(ci. Prost# implementacj# interfejsu

MindReader

jest klasa

Magician

:

package com.springinaction.springidol;

public class Magician implements MindReader{
private String thoughts;

public void interceptThoughts(String thoughts){
System.out.println("PrzechwytujU myXli ochotnika: ");
this.thoughts=thoughts;
}

public StringgetThoughts(){
return thoughts;
}
}

Musimy dostarczy< czytaj#cemu w my(lach kogo(, kogo my(li móg0by odczyta<. W tym
celu zdefiniujemy interfejs

Thinker

:

package com.springinaction.springidol;

public interface Thinker{
void thinkOfSomething(String thoughts);
}

Klasa

Volunteer

stanowi podstawow# implementacj, interfejsu

Thinker

:

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

124

R

OZDZIA'

4.

Aspektowy Spring

package com.springinaction.springidol;

public class Volunteer implements Thinker{
private String thoughts;

public void thinkOfSomething(String thoughts){
this.thoughts = thoughts;
}

public String getThoughts(){
return thoughts;
}
}

Szczegó0y klasy

Volunteer

nie s# jako( strasznie interesuj#ce ani wa'ne. Interesuj#cy jest

sposób, w jaki klasa

Magician

b,dzie przechwytywa< my(li klasy

Volunteer

za pomoc#

Spring AOP.

Aby osi#gn#< taki stopie8 telepatii, b,dziemy musieli skorzysta< z tych samych ele-

mentów

<aop:aspect>

oraz

<aop:before>

, których u'ywali(my ju' wcze(niej. Lecz tym

razem skonfigurujemy je w taki sposób, by przekazywa0y do porady parametry metody
docelowej.

<aop:config>
<aop:aspectref="magician">
<aop:pointcutid="thinking"
expression="execution(*
com.springinaction.springidol.Thinker.thinkOfSomething(String))
and args(thoughts)"/>

<aop:before
pointcut-ref="thinking"
method="interceptThoughts"
arg-names="thoughts" />
</aop:aspect>
</aop:config>

Klucz do umiej,tno(ci pozazmys0owych klasy

Magician

znajduje si, w definicji punktu

przeci,cia oraz atrybucie

arg-names

elementu

<aop:before>

. Punkt przeci,cia identy-

fikuje metod,

thinkOfSomething()

klasy

Thinker

, oczekuj#c# argumentu typu

String

.

Nast,pnie za( parametr

args

pozwala zarejestrowa< argument jako warto(<

thoughts

.

Jednocze(nie deklaracja porady

<aop:before>

odwo0uje si, do argumentu

thoughts

,

wskazuj#c, 'e powinien on zosta< przekazany do metody

interceptThoughts()

.

Od tego momentu, kiedykolwiek zostanie wywo0ana metoda

thinkOfSomething()

w beanie

volunteer

, klasa

Magician

przechwyci te my(li. By to udowodni<, utworzymy

prost# klas, testow# z poni'sz# metod#:

@Test
public void magicianShouldReadVolunteersMind(){
volunteer.thinkOfSomething("Dama Kier");

assertEquals("Dama Kier", magician.getThoughts());
}

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.3.

Deklarujemy aspekty w j"zyku XML

125

Bardziej szczegó0owo zagadnienie pisania w Springu testów jednostkowych i testów
integracyjnych omówimy w nast,pnym rozdziale. Na razie zapami,tajmy, 'e rezultat testu
oka'e si, pozytywny, poniewa'

Magician

zawsze b,dzie wiedzia0 wszystko, o czymkol-

wiek

Volunteer

pomy(li.

Teraz dowiedzmy si,, w jaki sposób u'y< techniki Spring AOP, by doda< now# funk-

cjonalno(< do istniej#cych obiektów dzi,ki mocy wprowadzenia.

4.3.4.

Wprowadzamy now7 funkcjonalnoGH przez aspekty

W niektórych j,zykach, jak Ruby czy Groovy, istnieje poj,cie klas otwartych. Umo'li-
wiaj# one dodawanie nowych metod do obiektu albo klasy bez konieczno(ci bezpo(red-
niego modyfikowania definicji takiego obiektu czy te' klasy. Niestety, Java nie jest j,zy-
kiem a' tak dynamicznym. Gdy klasa zosta0a skompilowana, niewiele mo'na zrobi<
w celu dodania do niej nowej funkcjonalno(ci.

Lecz je(li si, dobrze zastanowi<, czy nie to w0a(nie starali(my si, robi< w tym roz-

dziale za pomoc# aspektów? Oczywi(cie, nie dodali(my do obiektów 'adnej nowej
metody, lecz dodawali(my nowe mechanizmy obok metod wcze(niej definiowanych przez
odpowiednie obiekty. Je(li aspekt mo'e opakowywa< istniej#ce metody w dodatkowe
mechanizmy, czemu nie doda< nowych metod do obiektu? W0a(ciwie, korzystaj#c
z aspektowej koncepcji zwanej wprowadzeniem, aspekty mog# dodawa< zupe0nie nowe
metody do beanów w Springu.

Przypomnijmy sobie, 'e w Springu aspekty s# po prostu obiektami po(rednicz#cymi,

które implementuj# te same interfejsy, co komponent docelowy. Jaki by0by skutek, gdyby,
poza tymi wspólnymi interfejsami, obiekt po(rednicz#cy implementowa0 jeszcze jaki(
inny interfejs? Wówczas ka'dy komponent realizuj#cy porad, aspektu sprawia0by wra'e-
nie, jakby tak'e implementowa0 ten nowy interfejs. Dzieje si, tak, mimo 'e klasa, której
instancj# jest nasz komponent, nie zawiera implementacji tego dodatkowego interfejsu.
Na rysunku 4.7 pokazano, jak to dzia0a.

Rysunek 4.7.

Spring AOP pozwala na wprowadzanie nowych

metod do komponentu. Obiekt po:rednicz4cy przechwytuje
wywo5ania i deleguje do innego obiektu, który implementuje
dan4 metodA

Na rysunku 4.7 mo'emy zauwa'y<, 'e w momencie wywo0ania wprowadzonego

interfejsu obiekt po(rednicz#cy deleguje wywo0anie do pewnego innego obiektu, który
zawiera implementacj, tego nowego interfejsu. W efekcie uzyskujemy pojedynczy kom-
ponent, którego implementacja jest rozdzielona pomi,dzy wi,cej ni' jedn# klas,.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

126

R

OZDZIA'

4.

Aspektowy Spring

By wcieli< ten pomys0 w 'ycie, powiedzmy, 'e chcemy wprowadzi< do klas wszyst-

kich wykonawców z naszych przyk0adów poni'szy interfejs

Contestant

:

package com.springinaction.springidol;

public interfaceContestant{
void receiveAward();
}

Zak0adamy, 'e mo'emy zajrze< do ka'dej implementacji klasy

Performer

i zmodyfiko-

wa< je wszystkie tak, aby implementowa0y tak'e interfejs

Contestant

. Z projektowego

punktu widzenia mo'e to jednak by< niezbyt rozwa'ny ruch (poniewa' implementacje
interfejsów

Contestant

i

Performer

niekoniecznie musz# w sensie logicznym zawiera< si,

nawzajem w sobie). Co wi,cej, mo'e nawet okaza< si, niemo'liwe, by zmieni< wszystkie
implementacje interfejsu

Performer

. Szczególnie je(li pracujemy z implementacjami

tworzonymi przez osoby trzecie, mo'emy nie mie< dost,pu do kodu Xród0owego.

Szcz,(liwie wprowadzenia przez aspekty mog# nam pomóc sobie z tym poradzi<,

nie wymagaj#c po(wi,cania decyzji projektowych lub inwazyjnych dzia0a8 wzgl,dem
istniej#cych implementacji. Aby skorzysta< z tego mechanizmu, musimy pos0u'y< si,
elementem

<aop:declare-parents>

:

<aop:aspect>
<aop:declare-parents
types-matching="com.springinaction.springidol.Performer+"
implement-interface="com.springinaction.springidol.Contestant"
default-impl="com.springinaction.springidol.GraciousContestant"
/>
</aop:aspect>

Jak sugeruje znaczenie nazwy elementu

<aop:declare-parents>

, pozwala on na zade-

klarowanie, 'e komponent, którego dotyczy porada, otrzyma nowe obiekty nadrz,dne
w hierarchii obiektów. W tym konkretnym wypadku deklarujemy za pomoc# atrybutu

types-matching

, 'e typy pasuj#ce do interfejsu

Performer

powinny posiada< tak'e, jako

klas, nadrz,dn#, interfejs

Contestant

(wskazany przez atrybut

implement-interface

).

Ostatni# spraw# do rozstrzygni,cia jest po0o'enie implementacji metod interfejsu

Contestant

.

Istniej# dwa sposoby, by wskaza< implementacj, wprowadzonego interfejsu. W tym

wypadku korzystamy z atrybutu

default-impl

, by wprost wskaza< implementacj, za

pomoc# jej w pe0ni kwalifikowanej nazwy klasy. Alternatywnie, mogliby(my wskaza<
implementacj, za pomoc# atrybutu

delegate-ref

:

<aop:declare-parents
types-matching="com.springinaction.springidol.Performer+"
implement-interface="com.springinaction.springidol.Contestant"
delegate-ref="contestantDelegate"
/>

Atrybut

delegate-ref

odwo0uje si, do komponentu w Springu jako delegacji wprowa-

dzenia. Zak0adamy tu, 'e komponent o nazwie

contestantDelegate

istnieje w kontek-

(cie Springa:

<bean id="contestantDelegate"
class="com.springinaction.springidol.GraciousContestant"/>

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.4.

U$ywamy adnotacji dla aspektów

127

Ró'nica mi,dzy bezpo(rednim wskazaniem delegacji za pomoc# atrybutu

default-impl

oraz po(rednim przez atrybut

delegate-ref

polega na tym, 'e w tym drugim rozwi#-

zaniu mamy komponent Springa, który sam mo'e podlega< wstrzykiwaniu, otrzyma<
porad, albo w jaki( inny sposób zosta< skonfigurowany przez Springa.

4.4.

UJywamy adnotacji dla aspektów

Podstawow# funkcj# wprowadzon# w wersji 5 AspectJ by0a mo'liwo(< u'ycia adnotacji
do tworzenia aspektów. We wcze(niejszych wersjach pisanie aspektów w AspectJ wyma-
ga0o nauki rozszerzenia do j,zyka Java. Lecz adnotacyjny model wprowadzony w AspectJ
upro(ci0 tworzenie aspektu z dowolnej klasy dzi,ki wprowadzeniu kilku nowych adno-
tacji. Ten nowy mechanizm jest znany pod nazw# @AspectJ.

Wracaj#c do klasy

Audience

, widzieli(my, 'e zawiera0a ona wszystkie funkcje, jakie

powinni realizowa< widzowie, lecz 'adnego ze szczegó0ów, które czyni0yby z tej klasy
aspekt. To zmusza0o nas do deklarowania porady i punktów przeci,cia w pliku XML.

Lecz dysponuj#c adnotacjami w stylu @AspectJ, mo'emy wróci< do naszej klasy

Audience

i uczyni< z niej aspekt, nie potrzebuj#c do tego celu 'adnej dodatkowej klasy

ani deklaracji komponentu. Na listingu 4.6 pokazano now# wersj, klasy

Audience

, dzi,ki

adnotacjom przemienion# w aspekt.

Listing 4.6. Opatrujemy klasA Audience adnotacj4, by utworzy> aspekt

package com.springinaction.springidol;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class Audience{
@Pointcut(
"execution(* com.springinaction.springidol.Performer.perform(..))")
public void performance() {
}

@Before("performance()")
public void takeSeats() {

Przed wystApem

System.out.println("Widzowie zajmujM miejsca.");
}

@Before("performance()")
public void turnOffCellPhones() {

Przed wystApem

System.out.println("Widzowie wyQMczajM telefony komórkowe.");
}

@AfterReturning("performance()")
public void applaud() {

Po wystApie

System.out.println("Brawooo! Oklaski!");
}

@AfterThrowing("performance()")

Definicja
punktu przeciAcia

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

128

R

OZDZIA'

4.

Aspektowy Spring

public void demandRefund() {

Po nieudanym wystApie

System.out.println("Buu! Oddajcie pieniMdze za bilety!");
}
}

Nowa wersja klasy

Audience

jest opatrzona adnotacj#

@Aspect

. Adnotacja ta wskazuje,

'e klasa nie jest ju' tylko jednym z wielu POJO, lecz jest aspektem.

Adnotacji

@Pointcut

u'ywamy do zdefiniowania punktu przeci,cia mo'liwego do wie-

lokrotnego u'ycia wewn#trz aspektu w stylu @AspectJ. Warto(< przekazana adnotacji

@Pointcut

jest wyra'eniem punktu przeci,cia — tu wskazuj#cym, 'e punkt przeci,cia

powinien zosta< dopasowany do metody

perform()

klasy

Performer

. Nazwa punktu prze-

ci,cia pochodzi od nazwy metody, do której zastosowana jest adnotacja. Zatem ten punkt
przeci,cia b,dzie si, nazywa0

performance()

. To, co w0a(ciwie znajduje si, w ciele

metody

performance()

, nie ma specjalnie znaczenia, w0a(ciwie mog0aby to by< metoda

pusta. Sama metoda jest tylko znacznikiem, zapewniaj#cym adnotacji

@Pointcut

punkt,

w którym b,dzie mog0a si, zaczepi<.

Ka'da spo(ród metod naszej widowni zosta0a opatrzona adnotacj# porady. Adnotacja

@Before

zosta0a zastosowana zarówno do metody

takeSeats()

, jak i do

turnOffCellPho

nes()

, wskazuj#c tym samym, 'e te dwie metody realizuj# porady before. Adnotacja

@AfterReturning

wskazuje, 'e metoda

applaud()

realizuje porad,

after-returning

. Za(

metoda

demandRefound()

otrzyma0a adnotacj,

@AfterThrowing

, zatem zostanie wywo0ana

w razie zg0oszenia jakich( wyj#tków podczas wyst,pu.

Nazwa punktu przeci,cia

performance()

jest przekazana jako warto(< parametru do

wszystkich adnotacji porad. W ten sposób informujemy metody porad, gdzie powinny
zosta< zastosowane.

Zauwa'my, 'e poza adnotacjami oraz metod#

performance()

— niewykonuj#c# 'ad-

nych operacji — klasa

Audience

pozosta0a funkcjonalnie bez zmian. To oznacza, 'e nadal

jest ona prostym obiektem Javy i mo'emy jej u'ywa< jako takiego obiektu. Nadal mo'emy
tak'e wi#za< t, klas, w Springu w nast,puj#cy sposób:

<bean id="audience"
class="com.springinaction.springidol.Audience" />

Poniewa' klasa

Audience

zawiera wszystko, co potrzebne, by zdefiniowa< jej w0asne

punkty przeci,cia i porady, ju' wi,cej nie potrzebujemy deklaracji punktów przeci,cia
i porad w pliku konfiguracyjnym XML. Pozosta0a tylko jedna czynno(<, jak# musimy
wykona<, aby Spring zacz#0 stosowa< klas,

Audience

jako aspekt. Nale'y zadeklarowa<

w kontek(cie Springa komponent automatycznego po(redniczenia, który przekszta0ca kom-
ponenty opatrzone adnotacjami w stylu @AspectJ w porady obiektów po(rednicz#cych.

Do tego celu Spring posiada klas, tworz#c# automatycznych po(redników, nazwan#

AnnotationAwareAspectJAutoProxyCreator

. Mo'emy zarejestrowa< obiekt klasy

Annota

tionAwareAspectJAutoProxyCreator

jako element

<bean>

w kontek(cie Springa, lecz

wymaga0oby to bardzo du'o pisania (uwierz mi, Czytelniku... ju' kilka razy zdarzy0o mi
si, pisa< tak# deklaracj,). Zamiast tego, w celu uproszczenia tej do(< d0ugiej nazwy,
Spring posiada specjalny element konfiguracyjny w przestrzeni nazw

aop

, który jest

znacznie 0atwiejszy do zapami,tania:

<aop:aspectj-autoproxy />

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.4.

U$ywamy adnotacji dla aspektów

129

Element

<aop:aspectj-autoproxy/>

utworzy w kontek(cie Springa komponent klasy

AnnotationAwareAspectJAutoProxyCreator

i b,dzie automatycznie po(redniczy0 w wywo-

0aniach z komponentów, których metody zostaj# dopasowane do punktów przeci,cia zde-
finiowanych za pomoc# adnotacji

@Pointcut

w beanach opatrzonych adnotacj#

@Aspect

.

By móc u'y< elementu konfiguracyjnego

<aop:aspectj-autoproxy>

, musimy pami,ta<

o umieszczeniu przestrzeni nazw

aop

w naszym pliku konfiguracyjnym Springa:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

Powinni(my by< (wiadomi, 'e element

<aop:aspectj-autoproxy>

korzysta jedynie z adno-

tacji w stylu @AspectJ jako przewodnika podczas tworzenia aspektów opartych na obiek-
tach po(rednicz#cych. Gdyby(my zajrzeli „pod mask,”, przekonaliby(my si,, 'e nadal
s# to aspekty w stylu Springa. To jest istotne, poniewa' oznacza, 'e cho< u'ywamy
adnotacji w stylu @AspectJ, nadal zachowuje wa'no(< ograniczenie do po(redniczenia
jedynie w wywo0aniach metod. Je(li potrzebowaliby(my wykorzysta< pe0ne mo'liwo(ci
frameworka AspectJ, b,dziemy musieli pos0u'y< si, bibliotekami uruchomieniowymi
AspectJ, zamiast polega< na Springu, pozwalaj#cym jedynie na tworzenie aspektów na
bazie obiektów po(rednicz#cych.

Warto tak'e wspomnie< w tym miejscu, 'e zarówno element

<aop:aspect>

, jak

i adnotacje w stylu @AspectJ s# efektywnymi sposobami na przekszta0cenie POJO
w aspekt. Element

<aop:aspect>

posiada jednak jedn# szczególn# zalet, w porównaniu

do @AspectJ. Polega ona na tym, 'e nie potrzebujemy kodu Xród0owego klasy, która
realizuje funkcjonalno(< aspektu. Korzystaj#c z @AspectJ, musimy opatrzy< adnota-
cjami klas, i metody, a to wymaga posiadania dost,pu do kodu Xród0owego. Element

<aop:aspect>

mo'e za( odwo0ywa< si, do dowolnego komponentu.

Teraz dowiemy si,, jak za pomoc# adnotacji w stylu AspectJ utworzy< porad,

around

.

4.4.1.

Tworzymy porad6 around za pomoc7 adnotacji

Podobnie jak w przypadku konfigurowania Spring AOP z u'yciem plików XML, korzy-
staj#c z adnotacji w stylu @AspectJ, nie jeste(my ograniczeni do porad

before

i

after

.

Mo'emy tak'e zdecydowa< si, na zastosowanie porady

around

. W tym celu powinni(my

u'y< adnotacji

@Around

, jak w poni'szym przyk0adzie:

@Around("performance()")
public voidwatchPerformance(ProceedingJoinPointjoinpoint){
try {
System.out.println("Widzowie zajmujM miejsca.");
System.out.println("Widzowie wyQMczajM telefony komórkowe.");

longstart=System.currentTimeMillis();
joinpoint.proceed();
longend=System.currentTimeMillis();

System.out.println("Brawooo! Oklaski!");

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

130

R

OZDZIA'

4.

Aspektowy Spring

System.out.println("WystUp trwaQ " + (end - start)
+ " miliskund.");
} catch(Throwable t){
System.out.println("Buu! Oddajcie pieniMdze za bilety!");
}
}

Adnotacja

@Around

wskazuje, 'e metoda

watchPerformance()

ma by< zastosowana jako

porada

around

w punkcie przeci,cia

performance

. Powinno to wygl#da< w dziwnie zna-

jomy sposób, poniewa' jest to dok0adnie ta sama metoda

watchPerformance()

, któr# wi-

dzieli(my wcze(niej. Jedyna ró'nica polega na tym, 'e teraz zosta0a ona opatrzona adno-
tacj#

@Around

.

Jak by< mo'e pami,tamy z wcze(niejszych przyk0adów, nie wolno zapomnie< o jaw-

nym wywo0aniu w poradzie

around

metody

proceed()

, co zapewnia wywo0anie metody

docelowej. Lecz samo opatrzenie metody adnotacj#

@Around

nie wystarczy do umo'liwie-

nia wywo0ania metody

proceed()

. Wiemy, 'e metoda, która b,dzie realizowa0a porad,

around

, musi otrzyma< jako argument obiekt

ProceedingJoinPoint

, a nast,pnie wywo0a<

metod,

proceed()

tego obiektu.

4.4.2.

Przekazujemy argumenty
do porad konfigurowanych przez adnotacje

Dostarczanie parametrów do porad za po(rednictwem adnotacji w stylu @AspectJ nie
ró'ni si, istotnie od sposobu, w jaki osi#gali(my to za pomoc# deklaracji aspektów
w plikach konfiguracyjnych XML Springa. W0a(ciwie, w sporej wi,kszo(ci elementy
j,zyka XML, których u'yli(my wcze(niej, przek0adaj# si, prawie bezpo(rednio na odpo-
wiedniki w postaci adnotacji w stylu @AspectJ, jak mo'emy si, przekona< na przyk0a-
dzie nowej wersji klasy

Magician

z listingu 4.7.

Listing 4.7. Tworzymy aspekt z klasy Magician za pomoc4 adnotacji w stylu
@AspectJ

package com.springinaction.springidol;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect public class Magician implements MindReader {
private String thoughts;

@Pointcut("execution(* com.springinaction.springidol."
+ "Thinker.thinkOfSomething(String)) && args(thoughts)")
public void thinking(String thoughts) {
}

@Before("thinking(thoughts)")

Przekazujemy parametry do porady

public void interceptThoughts(String thoughts) {
System.out.println("PrzechwytujU myXli ochotnika: " + thoughts);
this.thoughts = thoughts;
}

public String getThoughts() {

Deklaracja
parametryzowanego
punktu przeciAcia

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.4.

U$ywamy adnotacji dla aspektów

131

return thoughts;
}
}

Element

<aop:pointcut>

zosta0 zast#piony adnotacj#

@Pointcut

, za( element

<aop:before>

zast#pi0a adnotacja

@Before

. Jedyna znacz#ca zmiana polega na tym, 'e adnotacje

@AspectJ mog#, bazuj#c na sk0adni Javy, wyznacza< szczegó0owo parametry przeka-
zywane do porady. Zatem w konfiguracji opartej na adnotacjach nie potrzebujemy
odpowiednika atrybutu

arg-names

z elementu

<aop:before>

.

4.4.3.

Tworzymy wprowadzenie za pomoc7 adnotacji

Wcze(niej zademonstrowali(my sposób na wprowadzenie nowego interfejsu do istniej#-
cego komponentu bez zmian w kodzie Xród0owym tego komponentu, za pomoc# ele-
mentu

<aop:declare-parents>

. Wró<my teraz raz jeszcze do tamtego przyk0adu, lecz tym

razem korzystaj#c z konfiguracji aspektów za pomoc# adnotacji.

Odpowiednikiem elementu

<aop:declare-parents>

w @AspectJ jest adnotacja

@Decla

re-Parents

. Adnotacja ta, u'yta wewn#trz klasy opatrzonej adnotacj#

@Aspect

, dzia0a

niemal identycznie jak element w XML, który zast#pi0a. U'ycie adnotacji

@DeclareParents

demonstruje listing 4.8.

Listing 4.8. Wprowadzamy interfejs Contestant za pomoc4 adnotacji w stylu
@AspectJ

package com.springinaction.springidol;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;

@Aspect public class ContestantIntroducer {

@DeclareParents(

Dodajemy interfejs Contestant

value = "com.springinaction.springidol.Performer+",
defaultImpl = GraciousContestant.class)
public static Contestant contestant;
}

Jak widzimy, klasa

ContestantIntroducer

jest aspektem. Jednak w odró'nieniu od aspek-

tów, jakie do tej pory utworzyli(my, nie realizuje ona porad before, after czy te' around.
Zamiast tego wprowadza do beanów klasy

Performer

interfejs

Contestant

. Podobnie jak

element

<aop:declare-parents>

, adnotacja

@DeclareParents

sk0ada si, z trzech cz,(ci:

Atrybut

value

jest odpowiednikiem atrybutu

types-matching

w elemencie

<aop:declare-parents>

. Identyfikuje on rodzaje komponentów, do których

wprowadzony b,dzie interfejs.

Atrybut

defaultImpl

jest odpowiednikiem atrybutu

default-impl

w elemencie

<aop:declare-parents>

. Identyfikuje on klas,, która b,dzie zawiera0a

implementacj, wprowadzonego interfejsu.

Statyczna w0a(ciwo(<, która jest opatrzona adnotacj#

@DeclareParents

,

identyfikuje wprowadzany interfejs.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

132

R

OZDZIA'

4.

Aspektowy Spring

Podobnie jak w przypadku ka'dego aspektu, musimy zadeklarowa< klas,

Contestant

Introducer

jako komponent w kontek(cie aplikacji Springa:

<bean class="com.springinaction.springidol.ContestantIntroducer" />

Element

<aop:aspect-autoproxy>

b,dzie tam si,ga0 po ten komponent. Gdy odkryje kom-

ponent opatrzony adnotacj#

@Aspect

, automatycznie utworzy obiekt po(rednicz#cy, który

b,dzie delegowa0 wywo0ania albo do docelowego komponentu, albo do obiektu imple-
mentuj#cego wprowadzony interfejs, zale'nie od tego, do którego z nich wywo0ywana
metoda nale'y.

Spraw#, która zwróci nasz# uwag,, jest fakt, 'e adnotacja

@DeclareParents

nie po-

siada odpowiednika atrybutu

delegate-ref

z elementu

<aop:declare-parents>

. Dzieje

si, tak, poniewa'

@DeclareParents

jest adnotacj# w stylu @AspectJ. @AspectJ jest pro-

jektem niezale'nym od Springa i z tego powodu jego adnotacje nie s# (wiadome istnienia
komponentów Springa. Wskutek tego, je(li potrzebujemy delegata do komponentu, który
zosta0 skonfigurowany w Springu, wówczas adnotacja

@DeclareParents

mo'e okaza< si,

nieodpowiednia i b,dziemy musieli uciec si, do zastosowania w konfiguracji elementu

<aop:declare-parents>

.

Spring AOP umo'liwia oddzielenie zagadnie8 przecinaj#cych od biznesowej logiki

aplikacji. Lecz, jak widzieli(my, aspekty w Springu ci#gle jeszcze s# oparte na obiektach
po(rednicz#cych i obowi#zuje je ograniczenie wy0#cznie do porad zwi#zanych z wywo-
0aniami metod. Je(li potrzebujemy czego( wi,cej ni' tylko obs0ugi po(redniczenia
w wywo0aniach metod, mo'e warto, by(my rozwa'yli u'ycie aspektów AspectJ. W nast,p-
nym punkcie zobaczymy, jak mo'na u'y< tradycyjnych aspektów z AspectJ w aplikacji
Springa.

4.5.

Wstrzykujemy aspekty z AspectJ

Cho< Spring AOP jest wystarczaj#cym rozwi#zaniem dla wielu zastosowa8 aspektów,
wypada s0abo w porównaniu z rozwi#zaniem AOP, jakim jest AspectJ. AspectJ obs0uguje
wiele typów punktów przeci,cia, które nie s# mo'liwe w Spring AOP.

Punkty przeci,cia w konstruktorach, na przyk0ad, s# przydatne, gdy potrzebujemy

zastosowa< porad, podczas tworzenia obiektów. W odró'nieniu od konstruktorów
w niektórych innych j,zykach obiektowych, konstruktory w Javie ró'ni# si, od zwyk0ych
metod. Z tego powodu bazuj#ca na obiektach po(rednicz#cych obs0uga programowania
aspektowego w Springu okazuje si, zdecydowanie niewystarczaj#ca, gdy chcemy zasto-
sowa< porad, podczas tworzenia obiektu.

W znacznej wi,kszo(ci aspekty w AspectJ s# niezale'ne od Springa. Cho< mog# by<

wplatane do aplikacji opartych na Javie, w tym aplikacji w Springu, zastosowanie aspek-
tów z AspectJ wprowadza odrobin, zamieszania po stronie Springa.

Jednak ka'dy dobrze zaprojektowany i znacz#cy aspekt prawdopodobnie b,dzie

zale'a0 od innych klas, które b,d# go wspomaga0y podczas dzia0ania. Je(li aspekt jest
zale'ny od jednej lub wi,cej klas w trakcie realizacji porady, mo'emy z poziomu tego
aspektu tworzy< instancje takich wspó0pracuj#cych obiektów. Albo, jeszcze lepiej, mo'emy
pos0u'y< si, wstrzykiwaniem zale'no(ci w Springu, by wstrzykiwa< komponenty do
aspektów w AspectJ.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.5.

Wstrzykujemy aspekty z AspectJ

133

By to zobrazowa<, utwórzmy kolejny aspekt dla turnieju talentów Idol Springa. Tur-

niej talentów potrzebuje jurora. Zatem utworzymy aspekt jurora w (rodowisku AspectJ.
Aspekt ten, zdefiniowany na listingu 4.9, nazwiemy

JudgeAspect

.

Listing 4.9. Implementacja w AspectJ jurora dla turnieju talentów

package com.springinaction.springidol;

public aspect JudgeAspect {
public JudgeAspect() {}

pointcut performance() : execution(* perform(..));

after() returning() : performance() {
System.out.println(criticismEngine.getCriticism());
}

// wstrzykni#ty obiekt
private CriticismEngine criticismEngine;
public void setCriticismEngine(CriticismEngine criticismEngine) {
this.criticismEngine = criticismEngine;
}
}

G0ównym zadaniem aspektu

JudgeAspect

jest komentowanie wyst,pu po jego zako8-

czeniu. Punkt przeci,cia

performance()

z listingu 4.9 zostanie dopasowany do metody

perform()

. W po0#czeniu z porad#

after()returning()

otrzymujemy aspekt, który reaguje

na zako8czenie wyst,pu.

Tym, co okazuje si, interesuj#ce w listingu 4.9, jest fakt, 'e juror nie komentuje

wyst,pu sam we w0asnym zakresie. Zamiast tego aspekt

JudgeAspect

wspó0pracuje

z obiektem

CriticismEngine

, wywo0uj#c jego metod,

getCriticism()

, aby uzyska< kry-

tyczny komentarz po wyst,pie. By unikn#< niepotrzebnego wi#zania mi,dzy aspektem

JudgeAspect

i obiektem

CriticismEngine

, aspekt

JudgeAspect

otrzymuje referencj, do

obiektu

CriticismEngine

za pomoc# wstrzykiwania przez metod, dost,pow#. Relacja

ta zosta0a zobrazowana na rysunku 4.8.

Rysunek 4.8.

Aspekty teW potrzebuj4 wstrzykiwania. Spring

moWe wstrzykiwa> zaleWno:ci do aspektów w AspectJ, zupe5nie
jakby to by5y zwyk5e komponenty

CriticismEngine

sam jest tylko interfejsem, który deklaruje prost# metod,

getCriticism()

.

Oto implementacja tego interfejsu (listing 4.10).

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

134

R

OZDZIA'

4.

Aspektowy Spring

Listing 4.10. Implementacja interfejsu CriticismEngine, z którego korzysta aspekt
JudgeAspect

package com.springinaction.springidol;

public class CriticismEngineImpl implements CriticismEngine {
public CriticismEngineImpl() {}

public String getCriticism() {
int i = (int) (Math.random() * criticismPool.length);

return criticismPool[i];
}

// wstrzykni#ty obiekt
private String[] criticismPool;
public void setCriticismPool(String[] criticismPool) {
this.criticismPool = criticismPool;
}
}

Klasa

CriticismEngineImpl

implementuje interfejs

CriticismEngine

, losowo wybieraj#c

krytyczny komentarz z listy wstrzykni,tej krytyki. Klasa ta mo'e zosta< zadeklarowana
jako bean w Springu za pomoc# poni'szego kodu w j,zyku XML:

<bean id="criticismEngine"
class="com.springinaction.springidol.CriticismEngineImpl">
<property name="criticisms">
<list>
<value>I'm not being rude, but that was appalling.</value>
<value>You may be the least talented person in this show.</value>
<value>Do everyone a favor and keep your day job.</value>
</list>
</property>
</bean>

Jak dot#d nieXle. Mamy ju' implementacj, interfejsu

CriticismEngine

, z którego b,dzie

korzysta0 aspekt

JudgeAspect

. Wszystko, co pozosta0o, to powi#zanie klasy

Criticism

EngineImpl

z aspektem

JudgeAspect

.

Zanim zademonstrujemy, jak zrealizowa< wstrzykiwanie, powinni(my wiedzie<, 'e

aspekty w AspectJ mog# by< wplatane do naszej aplikacji zupe0nie bez anga'owania
Springa. Jednak je(li chcemy u'y< wstrzykiwania zale'no(ci w Springu, by wstrzykiwa<
klasy wspó0pracuj#ce do aspektu w AspectJ, musimy zadeklarowa< aspekt jako element

<bean>

w konfiguracji Springa. Poni'sza deklaracja elementu

<bean>

realizuje wstrzy-

kiwanie beana

criticismEngine

do aspektu

JudgeAspect

:

<bean class="com.springinaction.springidol.JudgeAspect"
factory-method="aspectOf">
<propertyname="criticismEngine" ref="criticismEngine"/>
</bean>

W du'ej cz,(ci ta deklaracja elementu

<bean>

nie ró'ni si, w istotny sposób od wszyst-

kich innych deklaracji komponentów, jakie wyst,puj# w Springu. Jedyna powa'na
ró'nica polega na u'yciu atrybutu

factory-method

. Normalnie instancje komponentów

w Springu tworzy kontener Springa, lecz aspekty w AspectJ s# tworzone przez bibliotek,

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

4.6.

Podsumowanie

135

uruchomieniow# AspectJ. Do momentu, gdy Spring uzyska mo'liwo(< wstrzykni,cia
komponentu typu

CriticismEngine

do aspektu

JudgeAspect

, istnieje ju' instancja klasy

JudgeAspect

.

Poniewa' Spring nie odpowiada za tworzenie instancji aspektu

JudgeAspect

, nie

mo'emy po prostu zadeklarowa< klasy

JudgeAspect

jako komponentu w Springu. Zamiast

tego potrzebujemy sposobu, by Spring uzyska0 uchwyt do instancji klasy

JudgeAspect

,

która zosta0a w0a(nie utworzona przez AspectJ, tak aby(my mogli wstrzykn#< do niej
obiekt

CriticismEngine

. Zgodnie z konwencj#, wszystkie aspekty w AspectJ posiadaj#

statyczn# metod,

aspectOf()

, która zwraca singleton b,d#cy instancj# aspektu. Zatem,

by uzyska< instancj, aspektu, musimy u'y< atrybutu

factory-method

, by wywo0a< metod,

aspectOf()

, zamiast próbowa< wywo0ywa< konstruktor klasy

JudgeAspect

.

W skrócie, Spring nie korzysta z deklaracji

<bean>

, jakiej u'ywali(my wcze(niej, do

tworzenia instancji klasy

JudgeAspect

— instancja ta zosta0a ju' utworzona przez biblio-

tek, uruchomieniow# AspectJ. Zamiast tego Spring otrzymuje referencj, do aspektu
przez metod,

aspectOf()

fabryki, a nast,pnie realizuje wstrzykiwanie do niego zale'-

no(ci zgodnie z przepisem w elemencie

<bean>

.

4.6.

Podsumowanie

Programowanie aspektowe jest pot,'nym uzupe0nieniem programowania obiektowego.
Dzi,ki aspektom mo'emy rozpocz#< grupowanie zachowa8 aplikacji, dotychczas roz-
proszonych po ca0ej aplikacji, w modu0ach wielokrotnego u'ytku. Mo'emy wówczas
zadeklarowa<, gdzie i w jaki sposób dane zachowanie b,dzie zastosowane. Pozwala to
na ograniczenie niepotrzebnego powielania kodu i pozwala, aby podczas konstruowania
klas skupi< si, na ich g0ównych funkcjach.

Spring zapewnia aspektowe (rodowisko uruchomieniowe, które pozwala nam na

dodawanie aspektów wokó0 wywo0a8 metod. Nauczyli(my si,, jak mo'emy wplata<
porady przed wywo0aniem metody, po jej wywo0aniu oraz wokó0 niego, a tak'e doda<
dostosowane zachowanie do obs0ugi wyj#tków.

Mamy mo'liwo(< podj,cia kilku decyzji co do sposobu u'ycia aspektów przez nasz#

aplikacj, w Springu. Wi#zanie porad i punktów przeci,cia w Springu jest znacznie prost-
sze dzi,ki dodaniu obs0ugi adnotacji @AspectJ i uproszczonemu schematowi konfiguracji.

Na koniec, zdarzaj# si, sytuacje, gdy Spring AOP jest mechanizmem niewystarcza-

j#cym i musimy przej(< na AspectJ, aby korzysta< z aspektów o wi,kszych mo'liwo(ciach.
Na wypadek takich sytuacji zerkn,li(my na sposób u'ycia Springa, by wstrzykiwa< zale'-
no(ci do aspektów w AspectJ.

Do tego momentu omówili(my podstawy frameworka Spring. Dowiedzieli(my si,,

jak skonfigurowa< kontener Springa i jak zastosowa< aspekty do obiektów zarz#dza-
nych przez Springa. Jak widzieli(my, te podstawowe techniki daj# (wietn# mo'liwo(<
tworzenia aplikacji z0o'onych z luXno powi#zanych obiektów. W nast,pnym rozdziale
dowiemy si,, w jaki sposób luXne wi#zanie przez techniki DI i AOP pozwala na testo-
wanie przez programist, i jak zapewni< pokrycie testami kodu w Springu.

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

136

R

OZDZIA'

4.

Aspektowy Spring

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Cz/!' 2

Podstawy aplikacji Springa

cz,(ci 1. omówili(my podstawowy kontener Springa i oferowane przez niego

mo'liwo(ci w zakresie wstrzykiwania zale'no(ci (DI) i programowania aspektowego
(AOP). Maj#c t, podstawow# wiedz,, w cz,(ci 2. dowiemy si,, w jaki sposób tworzy<
aplikacje biznesowe w (rodowisku Springa.

Wi,kszo(< aplikacji utrwala informacje biznesowe w relacyjnej bazie danych. Roz-

dzia0 5., „Korzystanie z bazy danych”, dostarczy informacji na temat wsparcia Springa
dla utrwalania danych. Jednym z omawianych w tym rozdziale zagadnie8 b,dzie wspar-
cie Springa dla JDBC, dzi,ki któremu mo'na wydatnie zredukowa< kod potrzebny przy
pracy z JDBC. Omówiona zostanie te' integracja Springa z rozwi#zaniami trwa0o(ci
opartymi na mechanizmach odwzorowa8 obiektowo-relacyjnych, takich jak Hibernate
czy JPA.

Utrwalone dane musz# pozosta< spójne. W rozdziale 6., „Zarz#dzanie transakcjami”,

nauczysz si, deklaratywnego stosowania strategii transakcyjnych w obiektach aplikacji
przy pomocy programowania aspektowego.

W rozdziale 7., „Budowanie aplikacji sieciowych za pomoc# Spring MVC”, poznasz

podstawy Spring MVC, frameworka sieciowego zbudowanego na bazie Springa. Odkry-
jesz szeroki wybór kontrolerów Spring MVC do obs0ugi '#da8 sieciowych i zobaczysz,
jak w przezroczysty sposób podpina< parametry '#dania pod obiekty biznesowe, dbaj#c
jednocze(nie o poprawno(< danych i obs0ug, b0,dów.

Z rozdzia0u 8., „Praca ze Spring Web Flow”, dowiesz si,, jak budowa< oparte na prze-

p0ywach, konwersacyjne aplikacje sieciowe, u'ywaj#c frameworka Spring Web Flow.

Jako 'e bezpiecze8stwo jest istotnym aspektem ka'dej aplikacji, w rozdziale 9.,

„Zabezpieczanie Springa”, omówimy wreszcie u'ycie frameworka Spring Security w celu
ochrony informacji aplikacji.

W

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Skorowidz

A

Acegi Security, 250
ACID, 173
ActiveMQ, 338
adnotacja

@Around, 129
@Aspect, 129
@AspectJ, 127
@Async, 395
@Autowired, 92–96, 391
@Bean, 104
@Configuration, 104
@Controller, 206
@DeclareParents, 131
@Entity, 161
@Inject, 97
@ManagedResource, 364
@PathVariable, 307
@Pointcut, 128
@PreAuthorize, 272
@Qualifier, 95, 98
@Repository, 163
@RequestMapping, 307, 331
@RequestParam, 207
@ResponseBody, 314
@RolesAllowed, 271
@Scheduled, 393
@Secured, 270
@SkipIt, 102
@StringedInstrument, 96
@Transactional, 180
@Value, 99

adnotacje standardowe, 92, 100
adres URL, 262

przep0ywu, 236
typu RESTful, 305
typu RESTless, 305
zdalnej us0ugi, 294

agent MBean, 359
algorytm

MD5, 269
szyfrowania, 379

AOP, aspect-oriented programming, 22, 30, 108
aplikacja Spitter, 255
aplikacje

klienckie JMS, 338
aplikacje sieciowe, 189

architektura JMS, 335
asembler

InterfaceBasedMBeanInfoAssembler, 363
MetadataMBeanInfoAssembler, 364
MethodExclusionMBeanInfo, 362
MethodNameBasedMBeanInfoAssembler, 361

asemblery informacji MBean, 361
AspectJ, 113, 115
aspekt, 29, 109, 114

Audience, 120
w XML, 117

asynchroniczna obs0uga komunikatów, 354
asynchroniczne

RPC, 352
wywo0ania, 353

atrybut

default-init-method, 60
delegate-ref, 126
destroy-method, 59
factory-method, 57
hash, 267
init-method, 59
p:song, 66
scope, 58
system-properties-mode, 376
value, 62

atrybuty

transakcji, 180
'#dania, 203

automatyczne

rejestrowanie, 103
wi#zanie, 85–90, 99, Patrz tak4e wi#zanie
wykrywanie, 85, 100

autoryzacja @PostAuthorize, 273
AWS, Amazon Web Service, 220

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

400

Skorowidz

B

bezpiecze8stwo

aplikacji sieciowych, 259
na poziomie widoku, 260
sieciowe, 253

biblioteka

JAXB, 324
znaczników, 330

blok catch, 142
b0,dy walidacji, 214, 216
brokery komunikatów, message brokers, 335, 338
brudne odczyty, dirty reads, 182
Burlap, 287

C

Caucho Burlap, 280
Caucho Hessian, 280
chciwe pobieranie, eager fetching, 158
ciasteczko, 269
CMT, container managed transactions, 174
CRUD, create read update delete, 309
cykl 'ycia komponentu, 37
czas wykonania, runtime, 155

D

dane przep0ywu, 231
DAO, Data Access Objects, 41, 140
definiowanie

aspektu audience, 122
atrybutów transakcji, 180
bazowego przep0ywu, 233
kafelków, 201
kontrolera, 195
punktów przeci,cia, 120
transakcji, 186
widoku, 202

deklarowanie

aspektów, 117
dostawcy uwierzytelnienia LDAP, 266
fabryki, 160
komponentu, 104
porad, 119
transakcji, 180, 184

desygnator, 116

bean(), 117
execution(), 116
within(), 116

DI, dependency injection, 19, 29, 50, 64, 132, 250
dodawanie funkcjonalno(ci, 125

domy(lne w0a(ciwo(ci, 376
dostawca uwierzytelnienia, 264, 266
dost,p do

adresu URL, 262
atrybutów komponentu, 368
danych, 41, 139, 154
filtrów serwletów, 252
informacji uwierzytelniaj#cych, 260
komponentów, 367
komponentów EJB, 385
metody, 272
S3, 220
sk0adników kolekcji, 81
szablonu JdbcTemplate, 146
us0ug, 290, 293
us0ug JMS, 352
us0ug RMI, 282
zdalnego komponentu, 367
zdalnych us0ug, 281

dost,p tylko do odczytu, 183
dowi#zanie szablonu JMS, 343

E

egzekutor przep0ywu, 225
EJB, Enterprise JavaBeans, 22
EJB 2, 24
eksport

asynchronicznej us0ugi, 353
komponentu, 359

eksporter

HttpInvokerServiceExporter, 292
JmsInvokerServiceExporter, 350
RmiServiceExporter, 284, 350

eksportowanie

komponentów, 358
us0ugi Burlap, 290
us0ugi Hessian, 288

element

<amq:connectionFactory>, 339
<aop:around>, 122
<aop:aspect-autoproxy>, 132
<aop:aspectj-autoproxy/>, 129
<aop:config>, 119
<aop:declare-parents>, 126
<aop:pointcut>, 120
<authentication-manager>, 264
<beans>, 51
<constructor-arg>, 54, 340
<context:annotation-config>, 92
<context:component-scan>, 100

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Skorowidz

401

<context:mbean-export>, 364
<decision-state>, 239
<div>, 202
<end-state>, 229
<entry>, 70, 359
<evaluate>, 232
<filter>, 252
<flow:flow-executor>, 225
<flow:flow-location>, 226
<flow:flow-location-pattern>, 225
<form>, 330
<global-method-security>, 270, 276
<http>, 253
<http-basic>, 256
<if>, 241
<input>, 244
<intercept-url>, 257
<jdbc-user-service>, 264
<jee:jndi-lookup>, 382
<jee:local-slsb>, 385
<jms:listener>, 350
<ldap-server>, 268
<list>, 67
<map>, 67, 70
<mvc:resources>, 193
<null/>, 72
<on-entry>, 246
<property>, 62
<props>, 67
<secured>, 247
<security:authentication>, 260
<security:authorize>, 261
<set>, 67, 69, 232
<sf:errors>, 214
<sf:form>, 330
<subflow-state>, 229
<task:annotation-driven/>, 393
<tx:advice>, 185
<tx:annotation-driven>, 186
<tx:method>, 185
<util:list>, 81

elementy konfiguracyjne, 67, 118
e-mail, 386

F

fabryka

komponentów, 36
mened'erów encji, 165
po0#cze8 JMS, 339
sesji Hibernate, 160

fantomy, phantom read, 182

filtr, 102

annotation, 102
aspectj, 102
assignable, 102
custom, 102
HiddenHttpMethodFilter, 331
regex, 102

filtry

serwletów, 250, 253
Spring Security, 253

format JSON, 329
formularz, 208

logowania, 254
rejestracyjny, 209

formularze typu RESTful, 329
funkcja hasRole(), 272
funkcjonalno(< porady, 110

H

has0o, 267
has0o szyfrowania, 379
Hessian, 287
Hibernate, 158, 162
hierarchia wyj#tków, 142

I

iBATIS, 139
IDE, 113
identyfikatory, 105
implementacja

SpitterDao, 163
SplitterController, 205

informacja o lokalizacji, 326
inicjalizacja na '#danie posiadacza, 57
instalacja

ActiveMQ, 339
Spring Web Flow, 224

interfejs

AlertService, 351
Contestant, 126
CriticismEngine, 134
DisposableBean, 60
InitializingBean, 60
Instrument, 61
javax.management.NotificationListener, 371
MailSender, 386
MindReader, 123
Performer, 50
Session, 160

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

402

Skorowidz

interfejs

SpitterService, 283
Thinker, 123

izolacja, isolation, 173, 183

J

JAX-RPC, 295
JAX-WS, 295
JDBC, 35, 139, 149–152, 158
JDO, Java Data Objects, 159, 164
jednostka

organizacyjna, organization unit, 267
utrwalania, persistence unit, 165

j,zyk

AspectJ, 113, 115
SpEL, 72, 80, 257

JMS, Java Message Service, 41, 334
JMX, Java Management Extensions, 357, 372
JNDI, Java Naming and Directory Interface, 147,

380–384, 396

JPA, Java Persistence API, 149, 164

zarz#dzane przez aplikacj,, 165
zarz#dzane przez kontener, 166

JSP, 330
JSR-330, 97
JTA, Java Transaction API, 174

K

kaskadowo(<, cascading, 159
katalog

LDAP, 263
META-INF, 165

klasa

Audience, 118, 127
Auditorium, 59
BraveKnight, 27, 31
CriticismEngineImpl, 134
DamselRescuingKnight, 25
HomeController, 196
HttpInvokerServiceExporter, 292
Instrumentalist, 61, 62
java.util.Properties, 81
JdbcDaoSupport, 146
JmsTemplate102, 343
Juggler, 51, 53
Magician, 130
MimeMessageHelper, 389
Minstrel, 33
Piano, 64

PoeticJuggler, 54, 56
Properties, 71
Saxophone, 63
SimpleJdbcDaoSupport, 157
Sonnet29, 55
SpitterEmailServiceImpl, 387
SpitterServiceEndpoint, 296
SpringBeanAutowiringSupport, 296
Stage, 57
StandardPBEStringEncryptor, 379
Volunteer, 123

klasy

bazowe DAO, 145, 156
otwarte, 125
singletonowe, 57
statyczne, 57
szablonowe, 144

klient

REST, 317
SpitterService, 285
us0ugi RMI Spitter, 285

klucz prywatny, 269
kod szablonowy, 34
kolejka spittle.alert.queue, 353
kolejki, queues, 335
kolekcje typu map, 69
komponent, 50, 59

MBeanServerConnectionFactoryBean, 368
BasicDataSource, 148
dataSource, 377
HessianServiceExporter, 288
JaxWsPortProxyFactoryBean, 299
Minstrel, 32
RmiServiceExporter, 288
SpitterEmailServiceImpl, 387
spitterService, 284
TransactionProxyFactoryBean, 180

komponenty

EJB, 385
encyjne, entity beans, 163
encyjne BMP, 163
encyjne CMP, 163
jako us0ugi, 292
MBean, 364
MDB, 348
sterowane komunikatami, 347
w kontenerze, 38
wysy0aj#ce poczt,, 387
zagnie'd'one, 65
zarz#dzane, managed beans, 357, 361, 367

dynamic MBeans, 358
model MBeans, 358

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Skorowidz

403

open MBeans, 358
standard MBeans, 357

komunikacja

asynchroniczna, 335
RPC, 338
synchroniczna, 334, 337

konfiguracja

Acegi, 251
beanów, 51
bezpiecze8stwa sieciowego, 253
brokera komunikatów, 338
danych szyfrowania, 379
fabryki mened'erów encji, 164
JPA, 165
konteneru, 52
kontrolera Hessian, 289
odbiorców komunikatów, 349
puli, 148
rejestru przep0ywów, 225
repozytorium, 263
serwera LDAP, 268
Spring MVC, 192, 194
Spring Web Flow, 224
Springa, 103, 105
us0ugi RMI, 283
Xród0a danych, 147

konflikt nazw komponentów, 366
koniec przep0ywu, 242
konsumowanie komunikatów, 346
konteksty aplikacji, 28, 36, 203
kontener, 36, 50, 60

odbiorcy komunikatów, 349
podstawowy, 39

kontrola nad atrybutami, 360
kontroler, 193

DisplaySpittleController, 304
HomeController, 195
spittle, 205

konwertery komunikatów HTTP, 314

L

LDAP, 266, 268
LDIF, LDAP Data Interchange Format, 268
leniwe 0adowanie, lazy loading, 158
leniwe 0adowanie obiektów JNDI, 383
limit czasowy, timeout, 184
Lingo, 352, 354
localhost, 268
logowanie, 254
logowanie przez formularz, 254
luXne wi#zanie, 27, 64

M

MBean, 357
MDB, message-driven bean, 334, 347
MDP, message-driven POJO, 348
mechanizm utrwalania danych, 169
mened'er

encji, 164
transakcji, 175

metadane, 321
metoda

addAttribute(), 207
addCustomer(), 242
addInline(), 390
addSpitter(), 154, 211
addSpitterFromForm(), 218
aspectOf(), 135
createMessage(), 345
createMimeMessage(), 388
createSpittle(), 310
delete(), 324
displaySpittle(), 305
embark(), 25, 27
exchange(), 327
getBean(), 58
getCriticism(), 133
getEmployeeById(), 35
getFirst(), 322
getForEntity(), 320
getForObject(), 320
getHeaders(), 321
getLastModified(), 322
getObject(), 346
getRecentSpittles(), 196
getSimpleJdbcTemplate(), 157
getSpitter(), 315
getSpittle(), 307
getStatusCode(), 322
hasPermission(), 274
hasProfanity(), 275
invoke(), 368
listSpittlesForSpitter(), 207
main(), 28
Math.random(), 76
perform(), 91
postForEntity(), 326
postForLocation(), 327
postForObject(), 325
postSpitterForObject(), 326
proceed(), 130
put(), 323

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

404

Skorowidz

metoda

putSpittle(), 309
queryNames(), 368
receive(), 346
retrieveSpittlesForSpitter(), 318, 321
saveImage(), 220
saveSpittle(), 179, 395
selectSong(), 75
send(), 345
sendSimpleSpittleEmail(), 388
sendSpittleEmailWithAttachment(), 389
setNotificationPublisher(), 371
setSong(), 62
setSpittlesPerPage(), 368
showHomePage(), 196, 360, 362
singBeforeQuest(), 33
toList(), 246
toUpperCase, 75
toUpperCase(), 75
updateSpitter(), 317
updateSpittle(), 323
watchPerformance(), 121–123

metody

asynchroniczne, 395
do przetwarzania zasobów, 308
dost,powe, 361
eksportowane, 363
fabryki, 56
HTTP, 308
idempotentne, 308
RestTemplate, 319
zaplanowane, 393

miejsca docelowe, destinations, 335

domy(lne, 345
komunikatów, 340, 345

MIME, Multipurpose Internet Mail Extensions,

388

model, 191
model-widok-kontroler, 42
modu0 AOP, 41
modu0y, 39
modu0y Spring Security, 251
MVC, Model-View-Controller, 42, 189

N

nadpisywanie w0a(ciwo(ci, 377
nag0ówek Accept, 315
negocjacja zawarto(ci, 311, 314
niepodzielno(<, atomicity, 173
niepowtarzalne odczyty, nonrepeatable reads, 182

O

obiekt

EntityManagerFactory, 167
HttpInvoker, 292
MDP, 349
ResponseEntity, 322

obiekty

dost,pu do danych, 41
nadpisuj#ce w0a(ciwo(ci, 374, 377
po(rednicz#ce, 299, 369
po(rednika zdalnego, 369
po(redników, 291
wywo0uj#ce HTTP, 294
zast,puj#ce w0a(ciwo(ci, 374, 378

obraz wewn,trzny, inline image, 390
obs0uga

AOP, 113
filtrów, 253
komunikatów, 335

publikacja-subskrypcja, 336
punkt-punkt, 336

komunikatów asynchroniczna, 354
komunikatów JMS, 351
plików, 218
powiadomie8, 370
REST, 303
RPC, 281
wyj#tków, 150, 341
'#da8, 212
'#da8 przep0ywu, 226

odbieranie

komunikatów, 341, 346, 349
powiadomie8, 371

odwzorowania obiektowo-relacyjne, 41, 159
odwzorowanie SimpleUrlHandlerMapping, 290
ograniczenia bezpiecze8stwa, 276
okresowe uruchamianie zada8, 394
operacje matematyczne, 76
operator

!, 116
&&, 116
?, 75
[], 82
and, 117
Elvis, 79
not, 117
or, 117
T(), 75, 246
wyboru, 82

operatory w SpEL, 76
ORM, object-relational mapping, 41, 139, 159

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Skorowidz

405

osadzanie parametrów w adresach, 306
OSGi Blueprint Container, 44

P

pakiet org.springframework.beans.factory.

annotation, 98

parametry nazwane, 156
plik

coupon.png, 389
db.properties, 375
deliveryWarning.jspx, 241
emailTemplate.vm, 392
foo.xml, 37
home.jsp, 203
knights.xml, 28
konfiguracyjny, 66
list.jsp, 208
persistence.xml, 165
spitter-security.xml, 252
spring-idol.xml, 52
users.ldif, 268

pliki

JAR, 40
LDIF, 268

pobieranie

danych, 152
zasobów, 320

podprzep0yw

order, 243
p0atno(ci, 245
zamówienia, 245

POJO, Plain Old Java Obiects, 22
pole

_hidden, 331
_method, 330

po0#czenie z baz# danych, 374
porada, 110, 119

after, 33, 119
around, 121, 129
before, 33, 119

porównywanie hase0, 267
postautoryzacja metod, 273
postfiltrowanie metod, 273
po(rednik RMI, 286
powiadomienia JMX, 370
powi#zania mi,dzy obiektami, 50
poziomy izolacji, 182
preautoryzacja metod, 272
producent widoków, 198, 200, 312
program Cron, 395

programowanie

aspektowe, 22, 30, 108
funkcyjne, 302
transakcji, 178

propagacja, 181
protokó0 JMXMP, 367
przechwytywanie '#da8, 257
przeci#'anie operacji, 319
przej(cia, transitions, 227, 230
przej(cia globalne, 231
przej(cie cancel, 231
przekazywanie argumentów do porad, 130
przekszta0canie

w komponent, 364
w aspekt, 33

przep0yw, 231

_flowExecutionKey, 239
bazowy, 233
customer, 242
identyfikuj#cy klienta, 237
nadrz,dny, 234

przestrze8 nazw, 52

amq, 339
Spring Security, 251

przesy0anie plików, 221
przetwarzanie

formularza, 208, 211
warunkowe, 78

publikacje komponentu zarz#dzanego, 365
publikator NotifcationPublisher, 370
pula komponentu BasicDataSource, 148
punkty

ko8cowe, 295–298
przeci,cia, 111, 132
z0#czenia, 110, 114

R

regu0a DRY, 120
regu0y walidacji, 213
rejestr przep0ywów, 225
relacja alternatywy, 116
repozytoria, 140
resolver danych wielocz,(ciowych, 221
REST, Representational State Transfer, 190, 221,

301, 318

RESTful, 304
RESTless, 303
RMI, Remote Method Invocation, 42, 280, 282
rodzaje

adnotacji, 92
mened'erów encji, 164
stanów, 227

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

406

Skorowidz

rozszerzenia Springa, 46
RPC, remote procedure call, 280, 350
rzutowanie kolekcji, 82

S

schematy dzia0ania, workflow, 189
serializacja obiektów, 291
serwer

JMXConnectorServer, 367
LDAP, 268
MBean, 359
pocztowy, 387

serwlet

dyspozytora, 191
nas0uchuj#cy, 204

sesja pocztowa JNDI, 387
sesje kontekstowe, 162
skanowanie komponentów, 102
sk0adowe przep0ywu, 227
SOA, service-oriented architecture, 294
specyfikacja LDIF, 268
SpEL, Spring Expression Language, 72, 80, 257
spójno(<, consistency, 173
Spring

3.0, 47
AOP, 117
Batch, 43
Dynamic Modules, 44
Faces, 48
Integration, 43
JavaScript, 48
LDAP, 44
Mobile, 44
MVC, 190, 255
Rich Client, 45
Roo, 45
Security, 43, 250
Security 2.0, 48
Security 3.0, 271
Social, 44
Web Flow, 43, 48, 224, 247
Web Services, 43
.NET, 45
-Flex, 45

sta0e propagacji, 181
stan

addCustomer, 242
buildOrder, 236
checkDeliveryArea, 238
createPizza, 242, 244
identifyCustomer, 235, 236

registrationForm, 240
showOrder, 242
takePayment, 236
thankCustomer, 236
welcome, 239, 241

stany, states, 227

akcji, 228
decyzyjne, 228
ko8cowe, 229, 236
obiektów, 317
pocz#tkowe, 235
podprzep0ywów, 229
widoków, 227, 243
zasobów, 315

sterownik JDBC, 149
stopnie izolacji, 183
szablon, template, 144

JdbcTemplate, 153, 155
JMS Springa, 340
JmsTemplate, 342
NamedParameterJdbcTemplate, 153
RestTemplate, 318
SimpleJdbcTemplate, 153, 155
TransactionTemplate, 179
Velocity, 391, 393

szablony

dost,pu do danych, 143
JDBC, 153
wiadomo(ci, 391

szyfrator 0a8cuchów, string encryptor, 379
szyfrowanie, 267
szyfrowanie w0a(ciwo(ci, 378

T

technologie zdalnego dost,pu, 281
tematy, topics, 335
testowanie, 42
testowanie kontrolera, 197
transakcje, 171

Hibernate, 176
Java Persistence API, 177
Java Transaction API, 178
JDBC, 175
programowe, 180

transformacja '#da8, 331
trwa0o(<, durability, 173
tworzenie

aspektów, 127
beanów, 59
fabryki po0#cze8, 339
klientów REST, 317

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Skorowidz

407

tworzenie

komponentów, 56
kwalifikatorów, 95
obiektów POJO, 347
odbiorcy komunikatów, 348
porady around, 129
punktów ko8cowych, 295
spittle’ów, 310
szablonów wiadomo(ci, 391
us0ugi RMI, 283
wprowadzenia, 131

typy MIME, 312

U

uaktualnianie na gor#co, 383
udost,pnianie

metod, 361
zdalnych komponentów, 367

uprawnienie

ROLE_ADMIN, 247
ROLE_SPITTER, 266

URI, uniform resorce identifier, 305
URL, uniform resource locator, 305
us0uga

Burlap, 290
Simple Storage Service, 219
Spitter, 187, 286, 290

us0ugi

asynchroniczne, 353
Hessian, 288
RMI, 282, 283
sieciowe, 42, 294
systemowe, 30
u'ytkownika, 264
zdalne, 280, 282, 300

usuwanie

komponentu, 60
spittle, 274
zasobów, 324

uwierzytelnianie

HTTP, 256
u'ytkowników, 263–269
za pomoc# bazy danych, 264
za pomoc# LDAP, 266

W

walidacja, 189, 213
warstwa sieciowa aplikacji, 190, 194
wiadomo(< MIME, 388

wi#zanie, 27

automatyczne, 85–90, 99

autodetect, 87, 90
byName, 86
byType, 86, 88
constructor, 87, 89

jawne, 91
kolekcji, 67
kolekcji typu map, 69
kolekcji w0a(ciwo(ci, 71
list, 68
komponentów EJB, 385
mi,dzy obiektami, 25
null, 72
obiektów JNDI, 380
opcjonalne, 94
punktów ko8cowych, 296
za pomoc# adnotacji, 92
za pomoc# wyra'e8, 72

widok, 191

formularza, 210
strony g0ównej, 202

widoki

Tiles, 200
wewn,trzne, 198

w0a(ciwo(ci

komponentów, 62
systemowe, 376

w0a(ciwo(<

connectionFactory, 354
database, 167
destination, 354
managedInterfaces, 363
notificationListenerMappings, 372
registrationBehaviorName, 366
serviceInterface, 354
spittlesPerPage, 358

wplatanie, 111
wprowadzenie, 111, 125
WSDL, 300
wspó0bie'no(<, 182
wstrzykiwanie

obiektów JNDI, 382
przez adnotacje, 99
przez konstruktor, 26, 56
przez wywo0anie metod, 62
referencji, 54, 63
zale'no(ci, 29, 50, 64, 132, 250

wycofanie transakcji, 184
wydajno(<

postrzegana, 395
rzeczywista, 395

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ

background image

Czytaj dalej...

408

Skorowidz

wyj#tek

CustomerNotFoundException, 240
DataAccessExeption, 143
java.rmi.RemoteException, 281
NullPointerException, 75
SQLException, 141, 151

wyj#tki

dost,pu do danych, 143
JDBC, 143
kontrolowane, checked, 184

wykrywanie komponentów, 100
wyliczenie PaymentType, 246
wylogowywanie, 256
wymiana zasobów, 327
wymuszanie HTTPS, 259
wyodr,bnianie konfiguracji, 374
wyra'enia

bezpiecze8stwa, 258
logiczne, 78
programu Cron, 395
regularne, 79
w SpEL, 73–76

wyra'enie hasRole(), 258
wysy0anie

danych zasobu, 325
formularzy, 329
komunikatów, 341, 344
plików, 217
spittle’a, 344
wiadomo(ci, 386–390
zasobów, 323

wyszukiwanie obiektów, 380
wy(wietlenie widoku, 207
wywo0ania zwrotne, callbacks, 144
wzorzec, 33, 192

Z

zabezpieczanie

metod, 270, 272
przep0ywu, 247
'#da8 sieciowych, 252

zabezpieczenia na poziomie kana0u, 258
zagadnienia

przecinaj#ce, 108
przekrojowe, 29

zakres

komponentów, 58
propagacji, 181

za0#czniki wiadomo(ci, 388
zapis pliku, 219
zapis w pami,ci podr,cznej, 383
zapytania SQL, 152
zarz#dzanie

stanem, 189
transakcjami, 174

zarz#dzany atrybut, managed attribute, 359
zasi,g

danych przep0ywu, 232
kontekstu, 59

zasoby REST, 303
zast,powanie

w0a(ciwo(ci, 375
zmiennych, 376

zdalne

us0ugi, 280, 282, 300
wywo0anie procedury, 280
wywo0ywanie metod, 42, 280

zdalny dost,p, remoting, 280
zdalny dost,p JMX, 367
zintegrowane (rodowisko programistyczne, 113
zmienne (rodowiskowe, 379
znacznik, Patrz tak4e element

<security:authentication>, 260
<security:authorize>, 261
<sf:errors>, 214
<sf:form>, 330

znak &, 117
znak kontynuacji wiersza, 17
znaki kropek (..), 116

=

Xród0o danych

JDBC, 149
JNDI, 147
z pul#, 147

>

'#dania przep0ywu, 226
'#danie

DELETE, 310, 324
GET, 309, 320
HttpServletRequest, 252
POST, 310, 325
PUT, 322

Kup ksi

ąĪkĊ

Pole

ü ksiąĪkĊ


Wyszukiwarka

Podobne podstrony:
informatyka android w akcji wydanie ii frank ableson ebook
Spring w Akcji Wydanie III
informatyka php obiekty wzorce narzedzia wydanie iii matt zandstra ebook
informatyka tworzenie stron www kurs wydanie iii radoslaw sokol ebook
informatyka linux komendy i polecenia wydanie iii lukasz sosna ebook
informatyka aplikacje w delphi przyklady wydanie iii teresa pamula ebook
informatyka programowanie uslug wcf wydanie iii juval l wy ebook
informatyka kuloodporne strony internetowe jak poprawic elastycznosc z wykorzystaniem xhtml a i css
informatyka praktyczny kurs java wydanie iii marcin lis ebook
informatyka objective c vademecum profesjonalisty wydanie iii stephen g kochan ebook
Spring w akcji Wydanie IV
informatyka bios leksykon wydanie iv andrzej pyrchla ebook
informatyka apache receptury wydanie ii rich bowen ebook
biznes i ekonomia lifehacker jak zyc i pracowac z glowa wydanie iii adam pash ebook
informatyka python wprowadzenie wydanie iv mark lutz ebook
Spring w akcji Wydanie IV sprwa4

więcej podobnych podstron