0% found this document useful (0 votes)
103 views36 pages

Aspektirano Programiranje Master

This document is the master's thesis of Ivan Cikić titled "Aspect Oriented Programming (methodology and implementations)" from 2008 at the University of Belgrade Faculty of Mathematics. The thesis discusses the methodology of aspect-oriented programming and its implementation in AspectJ. It provides an overview of aspect-oriented programming concepts such as join points, pointcuts, advice, and weaving. It also gives examples of using AOP to improve implementations of design patterns such as the Observer pattern. The thesis is written in Serbian.

Uploaded by

aleksandar7
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
103 views36 pages

Aspektirano Programiranje Master

This document is the master's thesis of Ivan Cikić titled "Aspect Oriented Programming (methodology and implementations)" from 2008 at the University of Belgrade Faculty of Mathematics. The thesis discusses the methodology of aspect-oriented programming and its implementation in AspectJ. It provides an overview of aspect-oriented programming concepts such as join points, pointcuts, advice, and weaving. It also gives examples of using AOP to improve implementations of design patterns such as the Observer pattern. The thesis is written in Serbian.

Uploaded by

aleksandar7
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 36

Univerzitet u Beogradu

Matematiki fakultet

Master teza

Aspektno Orijentisano Programiranje


(metodologija i implementacije)

Ivan Ciki

Mentor: Duan Toi

Beograd
2008
Aspektno Orijentisano Programiranje Ivan Ciki

Sadraj

1. Uvod.............................................................................................. 3
2. AOP metodologija ......................................................................... 4
2.1 Simptomi isprepletanih dunosti ..................................................................... 4
2.1.1 Preplitanje koda .................................................................................................... 4
2.1.2 Rasipanje koda ...................................................................................................... 5
2.2 Posledice nemodularnosti .............................................................................. 6
2.3 Modularnost uz pomo AOP-a ....................................................................... 7
2.4 AOP specifikacija jezika ................................................................................. 9
2.5 AOP implementacija ....................................................................................... 9
2.6 AOP terminologija......................................................................................... 11
2.7 Istorija AOP-a ............................................................................................... 11
2.8 Prednosti i mane AOP-a............................................................................... 12
3. AspectJ ....................................................................................... 13
3.1 Take spajanja (Join Points) ........................................................................ 13
3.2 Take preseka (Pointcuts)............................................................................ 14
3.2.1 AspectJ jezik za izraavanje taaka preseka ....................................................... 14
3.2.1.1 Sintaksa potpisa programskih elementa............................................................................ 15
3.2.1.2 Podela taaka preseka ...................................................................................................... 16
3.2.1.2.1 Direktne take preseka .................................................................................................. 16
3.2.1.2.2 Indirektne take preseka ................................................................................................ 17
3.3 Savet (Advice) .............................................................................................. 18
3.3.1 Klasifikacija saveta............................................................................................... 18
3.4 Statiko preplitanje ....................................................................................... 20
3.4.1 Meu-tipovne deklaracije ..................................................................................... 20
3.4.2 Upozorenja/greke prilikom kompajliranja ............................................................ 20
3.5 AspectJ tkalac (Weaver)............................................................................... 21
3.5.1 Mehanizimi umetanja koda................................................................................... 21
4. Objektno Orjentisani Dizajn (OOD) i AOP ................................... 22
4.1 Isprepletana struktura projektnih obrazaca................................................... 22
4.2 Izazovi u implementaciji projektnih obrazaca ............................................... 22
4.3 Primer korienja AspectJ-a u implementaciji projektnih obrazaca:
Observer obrazac ............................................................................................... 22
4.3.1. Subjekat i Posmatra uloge................................................................................. 24
4.3.2. Subjekt-Posmatra veza ..................................................................................... 24
4.3.3 Opta logika auriranja ........................................................................................ 25
4.3.4 Konkretni aspekti u Observer obrascu ................................................................. 25
4.4 Poboljanja u implementaciji projektnih obrazaca koristei AOP ................. 25
5. Zakljuak ..................................................................................... 27
Dodatak - Primer implementacije bankarskog sistema koristei AOP28
D.1. Pregled reenja implementacije i korienih tehnologija............................. 28
D.2. Implementacija kontrole pristupa (sigurnosne logike) ................................. 31
D.3. Validacija ulaznih podataka ....................................................................... 33
D.4. Upravljanje transakcijama u radu sa bazom podataka................................ 34
D.5. Logovanje izvrenih operacija..................................................................... 35
Reference ....................................................................................... 36

2
1. Uvod

Softverski sistemi svakim danom postaju sve kompleksniji i svi indikatori pokazuju da e se takav
trend nastaviti u budunosti. Programeri se susreu sa sve sloenijim i obimnijim zahtevima,
samim tim je sve tee napraviti dobar dizajn, tj. dizajn koji e uzeti u obzir kako sadanje zahteve
tako i potencijalne budue pravce razvoja sistema.
Klju u borbi sa kompleksnou softvera jeste modularizacija. Dekompozicijom problema na
manje celine - potprobleme, i reavajui svaku celinu pojedinano, lake se dolazi do
zadovoljavajueg dizajna i implementacije celog sistema. Svaki od prepoznatih potproblema u
sistemu predstavlja jednu funkcionalnost sistema, odnosno jednu dunost (concern) koju sistem
mora da ispuni da bi obavljao svoju funkciju. Prema tome, softverski sistem moemo definisati
kao skup dunosti koje mora da ispuni. Sve dunosti koje sistem mora da zadovolji moemo
podeliti u dve kategorije:
Centralna (core) dunost koja opisuje glavnu funkciju jednog modula i karakteristina je
samo za taj modul.
Isprepletane (crosscutting) dunosti koje opisuju sporedne funkcije sistema prisutne u
mnogobrojnim modulima.

Na primer, u bankarskom sistemu, osnovna dunost sistema jeste da vodi rauna o klijenima i
raunima, izraunava kamate, obavlja transakcije izmedju banaka, itd. Svaku od ovih dunosti
nazivamo centralnim dunostima koje sistem mora da zadovolji. Medjutim, pored ovih, glavnih
dunosti, svaka aplikacija sa poslovnom primenom mora zadovoljiti jo mnogo drugih,
sporednih dunosti, koje se prepliu sa svim centralnim modulima: identifikacija i autorizacija
korisnika, logovanje akcija, keiranje podataka, nadgledanje peformansi sistema, upravljanje
transakcijama nad bazom podataka i mnogo drugih. Provera identiteta korisnika je neophodna u
svakom modulu koji mora da ispuni odreene sigurnosne zahteve, upravljanje transakcijama je
potrebno na svakom mestu u sistemu koji komunicira sa bazom podataka itd. Takve dunosti
sistema nazivamo isprepletane.

Objektno orjentisano programiranje (OOP), najrasprostranjenija metodologija danas, uvela je u


programiranje objektnu apstrakciju i modularizaciju. Zbog toga, OOP je odlian pristup u
implementaciji centralnih modula sistema, odnosno zadovoljavanju centralnih dunosti sistema.
Snaga OOP jeste u dekompoziciji sistema na manje objekte i modelovanju ponaanja svakog
objekta. Medjutim, OOP nije najbolji nain za realizaciju isprepletanih dunosti jer dovodi do
rasipanja koda neophodnog za implementaciju takve funkcionalnosti u mnogo drugih modula. Na
primer, u implementaciji centralnog modula esto se moe videti kd koji se bavi upravljanjem
transakcijama, hvatanjem greaka ili logovanjem. Ukratko, tipian OOP dovodi do nepoeljne,
vrste veze (tight coupling) izmedju centralnih i isprepletanih dunosti sistema. Uvodjenje nove
isprepletane dunosti koju sistem mora da zadovolji ili modifikovanje postojee moe dovesti do
modifikacija u relevantnom centralnom modulu. Ovde na scenu stupa Aspektno Orjentisano
Programiranje (AOP).

AOP je metodologija koja omoguava razdvajanje isprepletanih dunosti sistema uvodei novu
jedinicu apstrakcije aspekt. Koristeci AOP, realizacija svake isprepletane dunosti sistema je
enkapsulirana u aspektu i ne dolazi do sjedinjavanja sa centralnim modulima. Fokus svakog
aspetka je specifina isprepletana dunost, ime se omoguava implementacija centralnih
modula koji nisu vie optereeni ispunjavanjem isprepletanih dunosti i slobodni su da evoluiraju
nezavisno od njih. Aspektni tkalac (weaver), entitet slian kompajleru, je zaduen za kompoziciju
finalnog sistema, kombinujui centralne i isprepletane module, zadovoljavajui sve dunosti
sistema. Taj process se zove tkanje (weaving). Rezultat procesa jeste da AOP uvodi
modularizaciju u isprepletene dunosti i dovodi do arhitekture sistema koja je laka za dizajn,
implementaciju i odravanje.
2. AOP metodologija
2.1 Simptomi isprepletanih dunosti
U uvodu smo uveli pojam centralnih (glavnih) i isprepletanih (sporednih) dunosti koje sistem
mora da zadovolji i realizuje. Slika 2.1 prikazuje realizaciju i interakciju ovih dunosti u jednom
modulu sistema. Ovaj graficki prikaz pokazuje sistem dobijen korienjem danas iroko
prihvaenih tehnika za implementaciju softvera, sistem u kome su raznovrsne dunosti sistema
medjusobno zamrene.

Slika 2.1: Sistem kao kompozicija vie dunosti. Svaki implementacioni modul sadri kd koji
realizuje vie od jedne dunosti sistema.

ist objektno orjentisani pristup implementaciji isprepletanih dunosti sistema dovodi do pojave
dva klasina neeljena simptoma: preplitanje koda (code tangling) i rasipanje koda (code
scaterring).

Preplitanje i rasipanje koda mogu se pojaviti takodje i kao posledica loeg dizajna i/ili
implementacije (npr. kopiranje istog koda na vie mesta). Takvi problemi se, naravno, mogu
razreiti u okvirima OOP. Medjutim, upotrebom OOP za realizaciju isprepletanih dunosti
sistema, problem preplitanja i rasipanja koda je uvek prisutan.

2.1.1 Preplitanje koda


Preplitanje koda se javlja u sluajevima kada jedan modul ispunjava vie dunosti sistema
istovremeno. Programer pri implementaciji jednog modula mora da vodi rauna o dunostima
sistema kao sto su poslovna logika, sinhronizacija, logovanje, optimizacija, upravljanje grekama,
kontrola pristupa, itd. Rezultat takve implementacije je preplitanje koda prikazano emom 2.2:
Slika 2.2: Preplitanje koda nastalo kao posledica simultane implementacije vie dunosti sistema
u jednom modulu.

Ilustrujmo ovaj princip kroz deo koda. Primer prikazuje implementaciju modula koji enkapsulira
poslovnu logiku u klasinom OOP stilu.

00 public class KonkretniServis extends ApstraktniServis {


01 ... definicija lanova klase
02 ... definicija logera
03 ... status auriranja kea
04 ... objekat potreban za kontrolu konkurentnosti
05 ... preklopljene metode
06 public void servisOperacija1(<parametri operacije>) {
07 ... provera indentiteta autorizacija
08 ... zakljuaj objekat koji kontrolie pristup klasi (thread-safety)
09 ... auriranje kea
10 ... poetak transakcije
11 ... loguj poetak operacije
12 ... Izvri centralnu operaciju
13 ... loguj kraj operacije
14 ... komituj transakciju
15 ... otkljuaj objekat za kontrolu konkurentnosti
}

Primer 2.1

Iako je svaki problem specifian, ovaj primer dobro prikazuje uobiajni problem sa kojim se
suoavaju programeri. I pored toga postoji konceptualna razdvojenost izmedju razliitih dunosti
sistema tokom izrade dizajna, tokom implementacije dolazi do medjusobnog preplitanja vie
dunosti u jednom modulu. Ovakva implementacija ne ispunjava neke od osnovnih principa
dobrog objektno orijentisanog dizajna, izmedju ostalih i Single Responsibility Principle - za
promenu klase nikada ne sme postojati vie od jednog razloga[10], kao i Open/Closed Principle
- softverski entiteti (klase, moduli, funkcije, itd) treba da budu otvoreni za nasledjivanje i zatvoreni
za promenu[11].

2.1.2 Rasipanje koda


Rasipanje koda nastaje kada jednu funkciju sistema implementiramo u vie modula. S obzirom
da su po definiciji isprepletane dunosti sistema prisutne u vie modula, njihove implementacije
su takodje prisutne u svakom od tih modula. Slika 2.3 ilustruje kako bi u bankarskom sistemu bila
implementirana kontrola pristupa koristeenjem konvencionalne tehnike.
Slika 2.3: Implementacija kontrole pristupa korienjem konvencionalne tehinke. U modulu za
kontrolu pristupa implementrana je logika za autorizaciju u javnim metodama. Svaki klijentski
modul mora da sadri kd koji poziva te metode.

I u sluaju dobro dizajniranog sigurnosnog modula koji nudi apstraktan API i sakriva detalje
implementacije, svaki klijentski modul (u ovom primeru modul za rad sa raunima, ATM modul i
modul za rad sa bazom podataka) mora da sadri kd koji poziva sigurnosni API. Taj kd je rasut
po svim modulima koji koriste sigurnosni modul i posledica toga je neenjena povezanost svih
modula kojima treba sigurnosna provera i samog sigurnosnog modula (primer 2.1, linija 07).

2.2 Posledice nemodularnosti


Preplitanje i rasipanje koda utiu negativno na dizajn i razvoj softvera na vie naina: oteano
praenje koda, niska produktivnost, nii nivo iskorienosti koda, lo kvalitet i oteana evolucija.
Oteano praenje koda - Simultana implementacija vie dunosti u modulu, dovodi do
nejasne veze izmedju dunosti sistema i njene implementacije, to oteava praenje
veze izmedju zahteva i implementacije. Na primer, u sluaju da elimo da nadjemo
implementaciju dunosti za autorizaciju korisnika, potencijalno bi morali da ispitamo sve
module u sistemu.
Niska produktivnost - Simultana implementacija vie dunosti u modulu prebacuje fokus
sa glavne na vie sporednih dunosti. Taj gubitak fokusa dovodi do smanjene
produktivnosti.
Nii nivo iskorienosti koda - U sluaju kada je u modulu implementirano vie dunosti
sistema, vea je verovatnoa da drugi sistemi kojima je potrebna slina funkcionalnost
nee moi da iskoriste ve postojei modul. Zamislimo implementaciju jednog servisa koji
zahteva sigurnosnu proveru pre nego omogui korisniku pristup. Nekom drugom projektu
moe trebati isti servis ali sa drugaijom proverom sigurnosti, dok trei projekat nema
potrebe za sigurnosnom proverom. U ovom sluaju implementacija servisa iz prvog
projekta ne moe se ponovo iskoristiti iako je logika samog servisa identina u sva tri
sluaja.
Lo kvalitet - Preplitanje koda oteava pregledanje koda i uoavanja potencijalnih
greaka. Na primer, da bi se izvrilo kvalitetno ispitivanje kvaliteta koda nad takvom
implementacijom modula, neophodno je uee eksperata u svakoj od oblasti koje taj
modul pokriva.
Oteana evolucija - Usled nejasnih zahteva i ogranienih resorsa esto dolazi do dizajna
koji reflektuje samo trenutne zahteve. Takav sistem je teko odravati i razvijati u skladu
sa buduim zahtevima. S obzirom da reenje nije modularno, budue prepravke
podrazumevaju modifikaciju mnogobrojnih modula. Veliki broj promena u implementaciji
moe dovesti do nekonzistentnosti i pojavljivanja novih greaka.
Svi ovi problemi su doveli do potrage za boljim pristupom pri dizajnu i implementaciji softvera, a
kao jedno od reenja pojavio se i AOP.

2.3 Modularnost uz pomo AOP-a


U OOP, centralni moduli mogu biti povezani slabom vezom koristei interfejse (loose coupling),
ali ne postoji nain da se takva veza uspostavi sa isprepletanim funkcionalnostima[5]. Razlog za
to je to se implementacija svih dunosti sistema sastoji iz dva dela, serverski deo (koji nudi niz
servisa) i klijentski deo (koji koristi te servise). OOP moe pomoi u modularizaciji serverskog
dela pomou klasa i interfejsa. Medjutim, kada je dunost sistema isprepletane prirode, klijentski
deo koda koji se sastoji od poziva servisa na serveru, rasut je svuda u sistemu.
Kao primer ovoga, posmatrajmo tipinu implementaciju isprepletane dunosti pomou OOP:
modul za autorizaciju koji definie servis kroz jedan interfejs (primer 2.2, linija 03). Upotreba
interfejsa oslabljuje vezu izmedju klijenata koji koriste servis i implementacija samog interfejsa.
Klijenti koji koriste interfejs (AccountServiceOOP u primeru 2.2) nisu svesni implementacije koju
zaista referenciraju. Bilo kakva promena u implementaciji servisa nee zahtevati promene u
implementaciji klijenta. ak i zamena trenutno korienog modula za autorizaciju sa drugim je
samo stvar instanciranja nove implementacije modula u klijentu, a to se moe izvriti bez ili sa
malo promena u klijentskom modulu. Ovaj aranman ipak zahteva da klijent sadri ugnjedene
pozive servisa za autorizaciju. Takvi pozivi su nephodni u svakom modulu koji koristi autorizaciju
(primer 2.2, linije 06, 15, 23).
00 public class AccountServiceOOP implements IAccountService {
01 IUserDao userDao;
02 IAccountDao accountDao;
03 IAuthorizationService authorizationService;
04
05 public List<Account> getAccountsForUser(User user) {
06 if (authorizationService.isAccessAllowed(user)) {
07 return accountDao.getAccountsForUser(user);
08 } else {
09 throw new SecurityException();
10 }
11 }
12
13 }
14 public void removeAccount(User user, Account account) {
15 if (authorizationService.isAccessAllowed(user, account)) {
16 user.getAccounts().remove(account);
17 userDao.saveOrUpdate(user);
18 } else {
19 throw new SecurityException();
20 }
21 }
22 public void saveOrUpdate(User user, Account account) {
23 if (authorizationService.isAccessAllowed(user, account)) {
24 user.getAccounts().add(account);
25 userDao.saveOrUpdate(user);
26 } else {
27 throw new SecurityException();
28 }
29 }
30 }
Primer 2.2. Primer implementacije modula za administraciju rauna u bankarskom sistemu
korienjem OOP metodologije. U svakoj metodi, svake klase gde je potrebna kontrola pristupa,
potreban je poziv metode koja ne ispunjava centralnu dunost modula

Koristei AOP, ni jedan modul nee sadrati pozive za autorizaciju. Slika 2.4 prikazuje
implementaciju iste sigurnosne provere prikazanu i na slici 2.3, samo koristeci AOP. Realizacija
kontrole pristupa u sistemu (implementacija servisa i poziv servisa) sada se nalazi izolovana u
sigurnosnom modulu i sigurnosnom aspektu.
Slika 2.4: Implementacija kontrole pristupa koristeenjem AOP tehnike. Aspekt za kontrolu
pristupa definie take preseka u kojima treba izvriti proveru indentiteta i autorizaciju i poziva
javne metode definisane na modulu za kontrolu pristupa prilikom izvravanja tih taaka preseka.
Klijentski moduli vie ne sadre kd za autorizaciju.

Zahtevi za sigurnosnom proverom u svim modulima su sada realizovani u samo jednom modulu
aspektu za kontrolu pristupa (AuthorizationAspect u primeru 2.3). Sa ovakvom modularizacijom,
svaka promena u logici sigurnosne provere e se reflektovati samo na aspekt za kontrolu
pristupa, potpuno izolujui klijentske module (AccountServiceAOP). Fundamentalna razlika koju
AOP donosi jeste obostrana nezavisnost pojedinanih dunosti sistema i nakon same
implementacije, ne samo u toku dizajna. Implementacija se lako povezuje sa odgovarajuom
dunou sistema koju realizuje, to kao rezultat daje sistem koji je jednostavnije razumeti,
implementairati i menjati.
00 public class AccountServiceAOP implements IAccountService {
01 IUserDao userDao;
02 IAccountDao accountDao;
03
04 public List<Account> getAccountsForUser(User user) {
05 return accountDao.getAccountsForUser(user);
06 }
07 public void removeAccount(User user, Account account) {
08 user.getAccounts().remove(account);
09 userDao.saveOrUpdate(user);
10 }
11 public void saveOrUpdate(User user, Account account) {
12 user.getAccounts().add(account);
13 userDao.saveOrUpdate(user);
14 }
15 }
16
17 public aspect AuthorizationAspect {
18 IAuthorizationService authorizationService;
19 pointcut secureAccess() :
20 execution(* org.matf.icikic.banking.service.AccountServiceAOP.*(..));
21 before(User user, Account account) :
22 secureAccess() && args(user, account) {
24 if (!authorizationService.isAccessAllowed(user, account)) {
25 throw new SecurityException();
26 }
27 }
28 }
Primer 2.3. Implementacija modula za administraciju rauna u bankarskom sistemu koja je u
potpunosti izolovana od kontrole pristupa i AspectJ implementacija aspekta koji e obaviti
sigurnosnu proveru pre svake metode u AccountServiceAOP klasi.
Do sada je bilo rei samo o AOP metodologiji. Vreme je da zaemo malo dublje i predjemo na
AOP implementaciju. Kao i svaka druga metodologija u programiranju, AOP se sastoji iz dva
dela[5]:
Specifikacija jezika - opisuje jezike konstrukcije i definie sintaksu.
Implementacija jezika - zaduena za verifikaciju i prevodjenje koda u izvrivu formu.
Uglavnom realizovano pomou neke vrste kompajlera.

2.4 AOP specifikacija jezika


Svaka implementacija AOP-a mora sadrati specifikaciju jezika kojim e se implementairati
individualne dunosti sistema i jezik kojim e se izraavati pravila za kompoziciju (preplitanje)
implementiranih dunosti u zajedniki sistem[5].

Implementacija individualnih dunosti sistema


Kao i u svakoj drugoj metodologiji, implementacija individualnih dunosti sistema se
izoluje u posebne module koje odlikuju trenutno stanje (podaci) i definisano ponaanje.
Na primer, modul koji implementira keiranje podataka u sistemu e sadrati kolekciju
keiranih objekata, proveravati vreme validnosti tih objekata, itd. Za implementaciju i
centralnih i isprepletanih funkcija sistema, uglavnom se koriste standardni jezici kao sto
su C++, Java i C#.
Specifikacija pravila preplitanja
Pravila preplitanja odredjuju nain na koji implementirane pojedinane dunosti treba
integrisati da bi se formirao konani sistem. Na primer, nakon implementiranog modula
za autorizaciju potrebno je uvesti taj modul u postojei sistem. U ovom sluaju pravila
preplitanja bi se sastojala od informacija koje operacije u sistemu zahtevaju kontrolisani
pristup (primer 2.3, linija 20) i pod kojim uslovima korisnicima treba dopustiti pristup (u
primeru 2.3 logika enkapsulirana u IAuthorizationService modulu). Prava mo AOP-a
jeste u jednostavnom predstavljanju pravila preplitanja.
S obzirom da sada moemo sve sporedne (isprepletane) dunosti sistema izdvojiti u
posebne module, glavna klasa brine samo o svojoj centralnoj dunosti.
public class KonkretniServis extends ApstraktniServis {
... definicija lanova klase
... preklopljene metode
public void servisOperacija1(<parametri operacije>) {
... izvri centralnu operaciju
}

Primer 2.4
U poredjenju sa kodom prikazanim u primeru 2.1, ova klasa ne sadri kd kojim se realizuju
sporedne dunosti, samo kd za glavnu dunost klase. Izabrana AOP implementacija e
spajanjem klasa i aspekata kreirati isprepletan (kombinovan) modul za izvravanje. Jezik koji se
koristi za specifikaciju pravila preplitanja moe biti ekstenzija postojeeg jezika (AspectJ je AOP
implementacija koja koristi Java jezik i definise ekstenziju Jave za definisanje pravila), ali moe i
deskriptivno definisati pravila preplitanja (pomou XML-a, Java anotacija, .NET atributa itd).

2.5 AOP implementacija


U AOP implementaciji izvravaju se dve operacije: kombinuje se individulane dunosti sistema
korienjem pravila preplitanja, a zatim se dobjeni rezultati konvertuje u izvriv kd. Za
izvravanje ovih operacija zaduen je AOP procesor zvani aspektni tkalac (weaver).
Aspektni tkalac moe biti implementiran na vie naina. Na primer, u sluaju AOP implementacija
baziranih na Javi, izvorni kd biva transformiran u isprepletan izvorni kd a zatim ga Java
kompjler konvertuje u bajtkod. U ovom pristupu postoji vie nedostataka, najvie u tome da se
dobijeni izvrivi kd teko moe debagovati koristei poetni izvorni kd. Drugi pristup jeste da se
izvorni kd prvo kompajlira u bajtkod korienjem klasinog Java kompajlera, a zatim se koristei
aspektni kompajer izvrava bajtkod manipulacija, tj. umeu se aspekti (videti poglavlje 3.5.1).
Slika 2.5: AOP implementacija zasnovana na aspektnom kompajleru.

Moe se i dodatno manipulisati nainom umetanja aspekata u klase, u sluaju da elimo pomeriti
proces preplitanja od kompaliranja ka izvravanju. U Java programskom jeziku za takve potrebe
koristiti se specijalni uitava klasa (class loader), koji prvo uitava bajtkod aspekata, a zatim ih
automatski umee u klase prilikom uitavanju klasa.
Opisani pristupi su razliiti u nainu i trenutku umetanja aspekata, ali se svi zasnivaju na
konceptu aspektnog kompajlera. Postoji drugi opte prihvaeni nain implementacije AOP,
zasnovan na korienju dinamiki kreiranih proxy objekata. U ovakvom pristupu svaki objekat u
koji treba umetnuti aspekte je obuhvaen proxy objektom. Na primer, Spring framework
implementira AOP kreirajui proxy objekte u trenutku izvravanja sistema, koji presreu pozive
definisanih metoda i zatim preusmeravaju te pozive ka ciljnim metodama.

Slika 2.6: Proxy objekat koji okruuje ciljni objekat, presree pozive metoda i izvrava dodatnu
logiku pre pozivanja metode na ciljnom objektu.
2.6 AOP terminologija
Kao i veina tehnologija, AOP je formirao sopstveni argon. Pojmovi uvek prisutni u diskusiji o
1
AOP-u jesu take spajanja, taka preseka i savet .
1. Take spajanja (join points) su jedinstveno prepoznatljive take u toku izvravanja
sistema. Primer takvih taka su izvravanje metode, instanciranje objekta, ili bacanje
izuzetaka. Take spajanja su prisutne u svakom sistemu, nisu vezane za AOP.
2. Taka preseka (pointcut) je konstrukcija kojom se odredjuju take spajanja koje
zadovoljavaju odredjeni kriterijum. Na primer, za aspekt za logovanje interesantni su
pozivi svih javnih metoda u sistemu.
3. Savet (advice) je konstrukcija koja menja ponaanje programa. Kada taka preseka
izabere odgovarajue take spajanja na scenu dolazi savet aspekta, koji sadri dodatnu
logiku koja se se umee i modifikuje ponasanje modula. Savet umee dodatno ponaanje
pre, posle ili okruuje selektovanu taku spajanja. Savet je forma dinamikog
preplitanja (dynamic crosscutting) jer utie na ponaanje programa u toku njegovog
izvravanja. Na primer, u implementaciji logovanja, savet je zaduen da zabelei ulazak
u svaku javnu metodu.
4. Pored dinamikog, postoji i statiko preplitanje koje omoguava promenu strukture
samog sistema. Upotrebom medju-tipovne deklaracije (inter-type declaration), mogue
je dodati u definiciju klase novu promentljivu.
5. Aspekt je konstrukcija u kojoj se izraavaju sve prethodno pomenute konstrukcije. Cilj
AOP-a je da postoji modul koji enkapsulira svu isprepletanu logiku, a aspekt je mesto gde
se definise ta logika. Aspekt sadri take preseka, savete i konstrukcije statikog
preplitanja.

Slika 2.7: Funkcionalnost aspekta (savet) se umee u toku izvravanja programa u jednoj ili vie
taaka.

Svaka AOP implementacija mora da sadri model taaka preseka (ine ga take spajanja i take
preseka), jer je to centralna konstrukcija oko koje se sve gradi. Medjutim, ne mora svaka
implementacija da podrava sve ostale delove generikog modela. Kao sto je ve pomenuto
Spring AOP akcenat stavlja na kombinovanje isprepletanih i centralnih dunosti sistema u toku
izvravanja programa i ne podrava statiko preplitanje.

2.7 Istorija AOP-a


Godinama unazad, teoretiari se slau da je najbolji nain za kreiranje robusnog sistema, a opet
lakog za razumevanje i odravanje, identifikacija i razdvajanje dunosti koje sistem mora da
ispuni. Ova tema je bolje poznata kao separation of concerns ili ukratko SoC[14] (termin koji

1
Detaljnije o svakom terminu u poglavljima 3.1, 3.2, 3.3, 3.4.
je u nauku o programiranju uveo poznati naunik E.W.Dijkstra[15]). U radu izdatom 1972. David
Parnas je dao predlog za najbolji nain postizanja SoC: modularizacija - proces kreiranja modula
koji sakrivaju svoje odluke medjusobno. OOP je pruilo moan nain za razdvajanje centralnih
dunosti sistema. Medjutim, nije se pokazalo tako dobro kod isprepletanih dunosti. Nekoliko
metodologija se pojavilo kao reenje za modularizaciju isprepletanih dunosti: meta-
programiranje, reflektivno prigramiranje, subjekt orjentisano, adaptivno programiranje, aspektno
orjentisano, itd. Velika zastupljenost AOP-a u razvoju novih aplikacija sa primenom u
svakodnevnom ivotu, pokazuje da je AOP izraslo u najpopularnije reenje.
Veliki deo istraivanja koje je dovelo do pojave AOP-a sprovedeno je u naunim institucijama.
Cristina Lopes i Gregor Kiczales iz Paolo Alto Research Center su jedni od prvih koji su radili na
razvoju AOP-a. Gregor[5] je takodje i zapoeo rad na AspectJ, prvoj implementaciji AOP-a.

2.8 Prednosti i mane AOP-a


Uvodjenje AOP-a dovodi do novog nivoa apstrakcije u programiranju. Apstrakcija smanjuje
kompleksnost posmatranog problema delei ga u izolovane celine module. S obzirom da svaki
modul predstavlja mali deo celog sistema, kompleksnost logike sadrane u modulu je smanjena
na nivo koji programer moe lake da shvati. Ali apstrakcija uvedena AOP-om dolazi uz
odredjenu cenu:
Uvodjenje nove apstrakcije (aspekata) u sistem je posao koji zahteva visok nivo znanja i
iskustva. Programeri moraju da primene odredjene dekompozicione tehnike da razdvoje
centralne i isprepletane dunosti sistema na pravi nain.
Apstrakcija po svojoj prirodi krije detalje implementacije. U software-skim sistemima vei
nivo apstrakcije uvek znai manje informacija o samoj implementaciji. Drugim reima
samo gledanje koda ne moe se preslikati na ono sto ce se deavati u trenutku
izvravanja (dobar primer toga jesu polimorfne funkcije u OOP, ne moe se znati koja
funkcija e se izvriti u trenutku kompajliranja). AOP uvodi jo veu kompleksnost u
praenju toka izvravanja programa (ne moe se znati koja akcija e se izvriti u
odredjenom trenutku, gledajui samo kd koji implementira centralnu dunost modula).

Pomenute mane su ipak mala cena koju treba platiti zarad prednosti koje donosi AOP:
Precizno definisane obaveze svakog modula - modul vie nije odgovoran za ispunjavanje
isprepletanih duznosti sistema.
Vii nivo modularizacije - AOP prua mehanizam za izolaciju svih dunosti sistema (ak i
isprepletanih) uz minimalnu medjusobnu vezu. Rezultat je sistem koji sadri manje
dupliranja koda i koji je laki za razumevanje i odravanje.
Laka evolucija sistema - uvodjenje nove funkcionalnosti u sistem se svodi na uvodjenje
novog aspekta i ne zahteva menjanje centralnih modula. Obrnuto, aspektni kompajler e
postojee aspekte umetati u svaki novo-uvedeni centralni modul.
Bolja iskorienost koda - bolja podela dunosti i labava povezanost dovodi do bolje
iskorienosti koda. AOP implementira svaku dunost u posebnom aspektu i svaki modul
je vezan za sistem slabijom vezom nego koristei konvencionalne tehinke. Precizinije
reeno, veza izmedju razliitih modula je prisutna samo u specifikaciji pravila za
kombinovanje isprepletanih dunosti sistema.
3. AspectJ
AspectJ[5] je aspektno-orjentisana ekstenzija programskog jezika Java. Sastoji se od
specifikacije i implementacije programskog jezika. Specifikacija definie sintaksu i semantiku
jezika kojim se pie kd. Implementacija AspectJ-a ukljuuje aspektni tkalac koji moe biti u
obliku kompajlera i linkera. Tkalac proizvodi bajtkod koji je u skladu sa Java specifikacijom
omoguavajui svakoj Java virtuelnoj maini (JVM) da izvrava taj kd.
AspectJ je nastao i razvijao se u poetku kao poseban jezik sa novim rezervisanim reima i
posebnim kompajlerom za prevodjenje tog jezika na bajtkod (tradicionalna sintaksa). Medjutim,
sa pojavom Jave 5 i uvodjenjem anotacija kao sredstvo za izraavanje meta-podataka, razvila se
alternativna sintaksa za izraavanje aspektno orjentisanih konstrukcija (@AspectJ sintaksa).
Dizajn modela taaka preseka AOP sistema omoguava programerima da piu robusne i lako
odrive sisteme ograniavajui pristup samo nekim takama spajanja. Jezik korien u AspectJ-u
za izraavanje taaka preseka je sofisticiran i omoguava selektovanje taaka spajanja na
osnovu strukturnih informacija kao to su tip objekta, ime objekta, argumenti, prisutne anotacije,
ali uzimajuu u obzir i kontrolni tok programa (control flow).

3.1 Take spajanja (Join Points)


Taka spajanja je svaki trenutak u izvravanju programa koji se moe jedistveno indentifikovati.
Poziv metode ili pristup promenljivoj su primeri take spajanja. Na slici 3.1 prikazan je
sekvencijalni UML dijagram bankarske transakcije i obeleene su take spajanja gde postoji
mogunost uvodjenja isprepletanog ponaanja.

Slika 3.1: Take spajanja u izvravnju programa (poziv i izvravanje metode su najee
koriene take spajanja).

Moemo videti vie taaka spajanja u trenutku poziva debit() metode na AccountService objektu.
Prva taka spajanja jeste poziv debit() metode, a odmah zatim i izvravanje iste metode. U toku
izvravanja nailazimo na nove take spajanja u vidu poziva i izvravanja find() metode na
AccountDao objektu i debit() metode na Account objektu. Poziv i izvravanje metoda nisu jedine
take spajanja, dodeljivanje vrednosti promenljivoj (npr. u toku izvravanja setBalance() metode
na Account objektu) je takodje taka spajanja.

Kategorizacija taaka spajanja u AspectJ[5]:


Na metodama
Najee koriene take spajanja. AspectJ podrava dve vrste taaka spajanja na
metodama: poziv i izvravanje metode. Izvravanje metode obuhvata izvravanje koda
unutar tela funkcije. Drugim reima to znai da se kd moe umetati pre, posle ili i pre i
posle tela metode. Poziv metode se deava na mestima gde se metoda poziva, tj. unutar
nekog druge programske konstrukcije iz koje se poziva metoda. U veini sluajeva
razlika izmedju take spajanja pri izvravanju i pozivu metode je zanemarljiva. Najbitinija
razlika se ogleda u mestu gde tkalac umee savet. U sluaju korienja izvravanja
metode tkalac umee savet unutar tela metode, dok prilikom poziva metode tkalac
umee savet svuda gde se poziva ta metoda. Iz ovoga sledi da kad god je mogue treba
potencirati umetanje koda prilikom izvravanja metoda.

Na konstruktorima
Slino kao u sluaju taaka spajanja na metodama samo to predstavljaju izvrenje i
poziv konstruktora.

Prilikom pristupa promenljivima


AspectJ podrava umetanje isprepletanog koda prilikom itanja i pisanja klasne ili
promenljive koja pripada instaci klase (ne podrava pristup lokalnim promenljivima).

Prilikom obradjivanja izuzetaka


AspectJ nudi mogunost procesiranja izuzetaka tako to podrava take spajanja koje
ustvari predstavaljaju catch blok u try/catch konstrukciji.

Prilikom inicijalizacije objekata


U inicijalizaciju ubrajamo vie podkategoraija: take spajanja u trenutku inicijalizacije
klasa (uitavanje klasa u Java virtuelnu mainu (JVM), inicijalizacija statikih
promenljivih, izvravanje statikih blokova), take spajanja u trenutku inicijalizacije
objekata (obuhvataju trenutak izmedju kraja izvravanja konstruktora nadklase do kraja
izvravanja prvog pozvanog konstruktora), take spajanja u trenutku preinicijalizacije
objekata (obuhvata prostor izmedju zvanja konstruktora i poziva konstruktora nadklase).

Prilikom izvravanja saveta


Kategorija koja obuhvata trenutak izvravanja bilo kog ve prisutnog saveta u sistemu.
Omoguava pisanje saveta kojima se mogu pratiti ponaanja saveta u celokupnom
sistemu.

3.2 Take preseka (Pointcuts)


Taka preseka je programska konstrukcija koja vri selekciju taaka spajanja i uva celokupni
kontekst odabrane take spajanja[5]. Klasa, interfejs, metod i promenljive su jedinstveno
odredjeni svojim potpisom. Taka preseka koristi ove potpise da bi opisala selektovanu taku
spajanja. esto sam potpis nije dovoljan za jedinstveno indentifikovanje take spajanja. AspectJ
nudi take preseka koje koriste informacije o toku izvravanja programa, kao to su celokupan
kontrolni tok programa (stek poziva metoda) koji je doveo do take spajanja. Kontekst take
spajanja su informacije o toku izvravanja programa asocirane uz svaku taku spajanja. Na
primer, u trenutku poziva metode kontekst podrazumeva objekat koji poziva metodu, objekat nad
kojim se poziva metoda (this), argumente, i anotacije nakaene na pozvanu metodu.

3.2.1 AspectJ jezik za izraavanje taaka preseka


AspectJ koristi isti jezik za izraavanje taaka preseka u tradicionalnoj i @AspectJ sintaksi. Taka
preseka se moe deklarisati unutar aspekta, klase ili interfejsa.
Primer definicije take preseka koja selektuje sve metode unutar Account klase dat je na slici 3.2:
Slika 3.2: Definicija take preseka. Sastoji se od rezervisane pointcut rei, imena i kriterijuma za
selekciju taaka spajanja.

Taka preseka se definie korienjem rezervisane rei pointcut. Ime take preseka se dodeljuje
da bi definisana taka mogla da se koristi kasnije u definiciji saveta aspekta. Deo nakon dvotake
je izraz koji selektuje take spajanja koristei tip take preseka i potpis programskih elemenata.

before() : accountOperation() {
telo saveta
}

AspectJ podrava Java logike operatore (!, ||, &&) u svom jeziku za izraavanje taaka preseka
ime omoguava konstrukciju kompleksnih pravila za odabir taaka spajanja kombinujui vie
jednostavnih taaka preseka.
Centralna konstrukcija u definiciji take preseka je potpis programskog elementa. S obzirom da
isprepletane dunosti sistema, po samoj definiciji, proimaju vie modula, jezik za izraavanje
taaka preseka mora pruiti ekonomian nain za izraavanje selekcionih kriterijuma. AspectJ
koristi doker elemente (wildcards) za selekciju elementa koji dele zajednike karateristike:
* jedan ili vie karaktera izuzimajui taku
.. jedan ili vise karatera ukljuujui taku
+ bilo koji podtip datog tipa
U zavisnosti od vrste potpisa programskog elementa ovi znaci dobijaju ua znaenja.

3.2.1.1 Sintaksa potpisa programskih elementa


1. abloni za izraavanje potpisa tipa
U AspectJ termin tip obuhvata klase, interfejse, primitivne tipove i aspekte. U ovim potpisima
specijalni znaci dobijaju ue znaenje:
* deo imena tipa ili paketa
.. svi direktni ili indirektni podpaketi
+ obeleava podtipove

Primer 3.1:
*Account - bilo koji tip ije se ime zavrava sa Account
java.*.Date - tip Date u bilo kom direktnom java podpaketu
java..* - bilo koji tip u java paketu ili bilo kom direktnom ili indirektnom podpaketu
@Entity Account - tip Account sa Entity anotacijom
*<Account> - bilo koji tip iji je parameter Account tip
@Named*Query User+ - tip User ukljuujui njegove podtipove koji su obeleeni anotacijom
ije ime poinje sa Named i zavrava sa Query
@(Secured || Sensitive)* - bilo koji tip koji ima ili @Secured ili @Sensitive anotaciju
2. abloni za izraavanje potpisa metoda i konstruktora
1
Potpis metode, odnosno konstruktora je odredjen imenom, tipom koji vraaju (samo za metode),
tipom na kojem je deklarisana, tipovima argumenta, definisanim nivoom pristupa i prisutnim
anotacijama.
Primer 3.2:
public void Account.set*(*) - bilo koji javni metod definisan na Account tipu, ije
ime poinje sa set, ne vraa rezultat i prima samo jedan argument bilo kog tipa.
* File.*(..) - svaki metod definisan na File tipu, koji prima 0 ili vie argumenta i
vraa rezultat bilo kog tipa.
@Transactional * *(..) - bilo koji metod oznaen sa @Transactional anotacijom.
!public * Account.*(..) - bilo koji ne-javni metod na Account tipu.
* *(..) throws SQLException - svaki metod koji je deklarisan da baca izuzetak tipa
SQLException.
* (@ThreadSafe *).*(..) - svaki metod definisan na tipu koji je oznaen
@ThreadSafe anotacijom.

3. abloni za izraavanje potpisa promenljive


Slino kao i u prethodnim sluajevima, potpis promenljive se koristi za selekciju taaka spajanja
koje odgovaraju itanju ili pisanju promenljivih.
Primer 3.3:
private float Account.balance privatna promenljiva balance tipa float
definisana na Account tipu.
* User.* - bilo koja promenljiva definisana na User tipu
private !static !final @Id * *.* - privatna, ne-statika i ne-finalna promenljiva
definisana na bilo kom tipu, koja je oznaena @Id anotacijom.

3.2.1.2 Podela taaka preseka


Postoje dva naina na koji se taka preseka uparuje sa takom spajanja u AspectJ[5]:
direktne take preseka koje se direktno uparuju sa kategorijama taaka spajanja koje
smo spominjali u 3.1.
indirektne take preseka koje se ne mogu direktno upariti sa odreenim takama
spajanja iz 3.1, ve selektuju take spajanja koristei dodatne infomacije o taki spajanja,
kao sto su tipovi objekata u trenutku izvravanja programa, programski tok (control flow) i
leksiki domen.

3.2.1.2.1 Direktne take preseka


Direktne take preseka prate odredjenu sintaksu da bi selektovali bilo koju vrstu podranih taaka
spajanja u AspectJ-u.
Kategorija taaka spajanja Sintaksa take preseka
Izvravanje metode execution(Potpis metode)
Poziv metode call(Potpis metode)
Izvravanje konstruktora execution(Potpis konstruktora)
Poziv konstruktora call(Potpis konstruktora)
Inicijalizacija klase Staticinitialization(Potpis tipa)
itanje promenljive get(Potpis tipa)
Pisanje promentljive set(Poptis tipa)
Procesiranje izuzetaka handler(Potpis tipa)
Inicijalizacija objekta initialization(Potpis konstruktora)
Pre-inijalizacija objekta preinitialization(Potpis konstruktora)
Izvravanje saveta adviceexecution()

1
Za razliku od potpisa metoda u Java jeziku, u potpis metode izraenom pomou AspectJ jezika za
definisanje taaka preseka i povratni tip pripada potpisu.
3.2.1.2.2 Indirektne take preseka
Indirektne take preseka odredjuju take spajanja po nekom dodatnom kriterijumu, ne samo
potpisu take spajanja. AspectJ nudi indirektne take preseka koje se zasnivaju na kontrolnom
toku programa, leksikoj strukturi, objektu nad kojim se trenutno izvrava program, argumentima,
anotacijama i uslovnim izrazima.

1. Take preseka na bazi kontrolnog toka programa


Ove take preseka selektuju take spajanja na osnovu programskog toka u drugim takama
spajanja odabranim od strane druge take preseka (programski tok take spajanja se moe
posmatrati kao tok programskih instrukcija koje nastaju kao rezultat pozivanja te take spajanja.
Npr. Account.debit() metoda poziva Account.getBalance(), pa kazemo da se poziv
Account.getBalance() desio unutar Account.debit() programskog toka).Postoje dve vrste taaka
preseka u AspectJ i oba zahtevaju drugu taku preseka kao argument.
cflow(<Taka preseka>) selektuje sve take spajanja u kontrolnom toku specifirane take
preseka ukljuujui i take spajanja koje odgovaraju datoj take preseka.
cflowbelow(<Taka preseka>) selektuje iste take spajanja kao i cflow(), izuzimajui
take spajanja koje odgovaraju datoj taki preseka.

Slika 3.3: Take preseka na bazi kontrolnog toka programa (cflow, cflowbelow) i take spajanja
koje selektuju na sekvencijalnom UML dijagramu.

2. Take preseka zasnovane na leksikoj strukturi


Leksike take preseka odabiraju take spajanja unutar leksikog domena date klase, aspekta,
metode. Postoje dve ovakve konstrukcije u AspectJ-u:
within(<Potpis tipa>) selektuje bilo koju taku spajanja unutar tela date klase ili aspekta
withincode(<Potpis metode>) selektuje bilo koju taku spajanja untar leksike strukture
metode ili konstruktora.
3. Take preseka zasnovane na tipu objekata pri izvravanju programa
this(<Tip>) selektuje take spajanja koje imaju asocirani this objekat datog tipa (take
spajanja gde this instaceof Tip izraz vraa true).
target(<Tip>) slino kao i this(), ali ispituje se objekat nad kojim se obavlja operacija, ciljni
objekat (npr. objekat nad kojim se poziva metoda).

4. Take preseka na bazi argumenta


args(<Tip>) poredi tip argumenta u toku izvravanja sa datim tipom u sluaju metode ili
konstruktora, sa baenim izuzetkom u sluaju procesiranja izuzetaka, u sluaju pristupa
promenljivoj radi pisanja poredi sa tipom nove vrednosti.

5. Take preseka zasnovane na uslovnim izrazima


Selektuju take spajanja na osnovu nekih provera u taki spajanja. Oblika su if(Logiki izraz).

3.3 Savet (Advice)


Savet je konstrukcija slina metodi pomou koje AspectJ realizuje isprepletane dunosti sistema.
Savet definie akciju koja se izvrava u takama spajanja odreenim pomou take preseka.
Detalji definicije saveta se razlikuju od klasifikacije (sekcija 3.3.1), ali se sastoji od tri osnovna
dela:
specifikacije da li e se izvravati pre, posle ili e okruivati izvravanje take spajanja.
definie koje take spajanja e biti savetovane.
telo saveta sadri kod koji e se izvravati prilikom izvravanja savetovane take
spajanja.

3.3.1 Klasifikacija saveta


AspectJ podrava tri vrste saveta:
pre savet (before advice) izvrava se pre izvravanja take spajanja.
Primer 3.4:
//Savet vri autorizaciju pre izvrenja bilo koje metode sa
//@Secure anotacijom
before() : execution(@Secure * *(..)) {
// autorizacija
}

posle savet (after advice) izvrava se nakon izvravanja take spajanja. Postoje tri
varijacije u zavisnosti od rezultata izvravanja:
 uvek posle (fter finally) izvrava se nakon izvravanja take spajanja
nezavisno od rezultata akcije.
Primer 3.5:
//Savet e se izvravati nakon svake metode u Account
//klasi, nezavisno od rezultata metode
after() : call(* Account.*(..)) {
// loguj povratnu vrednost
}

 posle uspenog povratka (after returning) izvrava se nakon


uspenog izvravanja akcije, tj. bez pojavljivanja greske.
Primer 3.6:
after() returning: call(* Account.*(..)) {
// loguj uspesno izvrsenje
}

AspectJ nudi mogunost upotrebe povratne vrednosti savetovanog metoda


Primer 3.7:

after() returning(Account account) :


call(AccountDao.find(..)) {
// operacija nad Account objektom
}

Ovaj savet se nee primeniti nad svim AccountDao.find() metodama ve samo


na onim koje vraaju Account objekat.

 posle greke (after throwing) izvrava se nakon neuspelog


izvravanja akcije, tj. bacanja izuzetka.
Primer 3.8:
after() throwing : call(* Account.*(..)) {
// operacija nakon pojave greke
}
Kao i u prethodnom sluaju postoji mogunost korienja baenog izuzetka.
Primer 3.9:
after() throwing(Throwable ex) : execution(* *(..)) {
// loguj izuzetak
loger.error(ex);
}

okruujui savet (around advice) okruuje izvravanje take spajanja. Ovaj savet je
specifian jer ima mogunost da izvri originalnu akciju sa ili bez menjanja konteksta nula
ili vie puta.
Tipina upotreba ovog saveta je da se obavi neka dodatna logika pre izvravanja same
take spajanja, da se prespoji (preskoi) izvravanje take spajanja i primeni neka
alternativna logka, ili obuhvati izvravanje take spajanja sa try/catch blokom,
transakcijom itd Unutar okruujueg saveta mora se pozvati specijalna rezervisana re
proceed() da bi se savetovana taka spajanja izvrila.
Primer 3.10:
void around(Account account, float amount)
: call (void Account.debit(float) throws BalanceExceptin)
&& target(account)
&& args(amount) {
try {
proceed(account, amount);
}catch(BalanceException ex) {
// loguj greku
}
}
Slika 3.4: Take u programskom toku koje aspekti mogu savetovati. Svaki krui na
sekvencijalnom dijagramu predstavlja mogunost umetanja pre i/ili posle saveta, a tok izmedju
dva odgovarajua kruia predstavlja mogunost za okruujui savet.

3.4 Statiko preplitanje


Take preseka i saveti zajedno ine dinamika pravila za umetanje koda. Statika pravila za
umetanje koda se izraavaju u vidu medju-tipovne deklaracije (inter-type declaration) i
upozorenjima/grekama prilikom kompajliranja (compile-time warnings/errors).

3.4.1 Meu-tipovne deklaracije


Meu-tipovna deklaracija je isprepletana konstrukcija koja menja statiku strukturu klase,
interfejsa ili aspekta. Omoguava dodavanje nove promenljive u definiciju klase, implementaciju
dodatnog interfejsa u definiciji klase ili dodavanje nove anotacije.
Primer 3.11:
private long AccessTracked.lastAccessTime
declare parents: CacheStatistics implements Observer
declare @method: public * Account.*(..):
@Secure(permission=adminOperation)
declare @field: private * (@Entity *).id:
@GeneratedValue(strategy=GenerationType.IDENTITY)

3.4.2 Upozorenja/greke prilikom kompajliranja


Omoguava definisanje dodatnih upozorenja i greaka koje e kompajler prijaviti u sluaju
ispunjenja postavljenih kriterijuma.

Primer 3.12:
declare error : callToUnsafeCode(): "This will result in crash";
declare warning : callToDaoLayer(): "Please ensure all calls to
data access layer are performed via service layer";

3.5 AspectJ tkalac (Weaver)


Poto se bajtkod proizveden pomou AspectJ kompajlera mora izvravati na JVM mora se
pridravati specifikacije Java bajt koda. To znai da se AOP konstrukcije moraju preslikati u Java
konstrukte. Sledi pojednostavljen pregled transformacije AspectJ koda u ist Java kd:
Aspekti se preslikavaju u klase (uglavnom singlton, ali postoje i drugaije asocijacije ),
1

svaki element i metod aspekta postaje i element klase.


Take preseka se preslikavaju u metode (bez tela). Mogu imati pridruene pomone
metode koje olakavaju odabir taaka spajanja u toku izvravanja koda.
Savet se mapira u jednu ili vie metoda. Tkalac umee pozive ovih metoda na mestu koje
odgovara pridruenoj taki preseka.

3.5.1 Mehanizimi umetanja koda


Da bi aspekti zadovoljili isprepletane dunosti sistema, neophodno je da tkalac uplete klase i
aspekte. AspectJ podrava tri naina preplitanja koda[5]:

Umetanje izvornog koda


Ulaz u tkalac su izvorni kd klasa i aspekata. Tkalac u ovom sluaju ima ulogu
kompajlera, procesira izvorni kd i proizvodi isprepleten bajtkod.
Umetanje binarnog koda
U ovom sluaju ulaz u tkalac su klase i aspekti u bajtkod formi, tj. pre ulaska u tkalac
klase i aspekti su odvojeno kompajlirane. Moe se rei da tkalac ima ulogu linkera u
ovom modu, koristei kompajliran kd proizvodi novi, isprepletan, binarni kd.
Umetanje prilikom uitavanja
Kao u sluaju binarnog umetanja, ulaz su kompajlirane klase i aspekti (u bajtkodu).
Aspekte umee specijalni agent u trenutku uitavanja klasa (load-time agent), koji moe
imati vie oblika: posaban uitava klasa (classloader), predprocesor klasa u
aplikacionom serveru ili samoj virtuelnom maini.

1
AspectJ podrava 4 vrste asocijacija aspekata: singlton(osnovni), po objektu, po programskom toku i po tipu.
4. Objektno Orjentisani Dizajn (OOD) i AOP
Projektni obrasci opisuju probleme koji se esto sreu u razvoju softvera i nude fleksibilna reenja
tih problema koja se mogu primeniti u mnogim situacijama. Svaki obrazac definiu problem
(opisuje kada se primenjuje obrazac), reenje (opisuje elemente koji ine dizajn, njihove
medjusobne odnose i obaveze) i posledice (rezultati primene obrasca i ustupke uinjene pri
tome)[3]. Kada su indentfikovani projektni obrasci smatrani su remek delom objektno orijentisanih
jezika. Medjutim, sa pojavom radova [7,8] koji su pokazivali da jezik koji se koristi za
implementaciju obrasca utie na njegovu implementaciju, poeli su da se istrauju efekti
aspektno orjentisanih tehnika na implementaciju objektno orjenitsanih obrazaca.
Projektni obrasci dodeljuju uloge (role) svojim uesnicima, primer toga su Subject i Observer u
Observer ili Component, Leaf i Composite u Composite obrascu [3]. Uloge definiu
funkcionalnosti uesnika u kontekstu obrasca. Istraivanjem je pokazan znaajan napredak u
modularnosti implementacija veine projektnih obrazaca korienjem AOP tehinka. Najvei
napredak je postignut u sluajevima gde je isprepletena struktura izmedju uloga i klasa koje
uestvuju u obrascu.

4.1 Isprepletana struktura projektnih obrazaca


Isprepletanost u struturi projektnog obrasca je uzrokovana razliitim vrstama uloga koje uestvuju
u obrascu i njihovom interakcijom sa klasama prisutnim u obrascu.
Uloge mogu biti definiue[4], to znai da uesnici u obrascu nemaju funkcionalnost izvan one
koja ga definie u obrascu, tj. da uloge kompletno odredjuju uesnike u obrascu. Na primer,
objekti koji imaju Facade ulogu [3] pruaju unifroman pristup nekom podsistemu i uobiajno je da
nemaju nikakvu drugu ulogu. Druga vrsta uloga su nadogradjene (superimposed)[4], koje su
dodeljene klasama koje imaju funkcionalnosti i obaveze van domena obrasca. Na primer, u
Observer obrascu klase koje imaju ulogu subjekata (Subject) i posmatraa (Observer) rade vie
od pukog ispunjavanja obaveze koje im namee obrazac.
U objektno orijentisanom programiranju definiue uloge su realizivane uglavnom nasledjivanjem
apstraktne bazne klase, ime se postie razliito, ali srodno ponaanje; nadogradjene uloge se
realizuju interfejsima koji definiu ponaanje i zaduenja klase.
U sluaju definiuih uloga, svaka jedinica apstrakcije (klasa) predstavlja jedinstvenu
funkcionalnost sistema, koja odgovara ulozi u obrascu i klasa se prirodno uklapa u svoju poziciju
u sistemu kao deo obrasca. Kod nadogradjenih uloga, uesnici imaju zaduenja izvan konteksta
projektnog obrasca i umetanjem klase sa takvom ulogom u kontekst obrasca dobijamo modul koji
u najboljem sluaju implementira dve dunosti sistema originalnu i specifinu za obrazac u kom
se koristi[4]. U ovakvim sluajevima modularnost je kompromitovana i upotrebom AOP jezika
mogue je izdvojiti dunosti specifine za obrazac u poseban modul aspekt.

4.2 Izazovi u implementaciji projektnih obrazaca


Tri najvanija izazova u realizaciji projektih obrazaca su vezana za implementaciju,
dokumentaciju i kompoziciju[4].
Implementacija projektnog obrasca vue vie nepoeljnih efekata. Poto obrazac utie na
strukturu sistema, a njegova implementacija zavisi od strukture sistema[2], implementacija
obrasca esto je prilagodjena objektu koji ga koristi. Ovo uzrokuje gubitak modularnosti i tekoe
u razlikovanju obrasca, objekta u kom se primenjuje, i celog objektnog modela[6]. Dodavanje ili
sklanjanje projektnog obrasca u/iz sistema esto je invazivan posao. Posledica ovoga je da iako
je obrasac ponovno upotrebljiv, sama implementacija nije.
Zbog invanzivne prirode implementacije projektnih obrazaca i preplitanja i rasipanja koda koje se
pojavljuje dokumentovanje obrazaca postaje teko izvodljivo.
Kompozicija obrazaca podrazumeva upotrebu vie obrazaca u istim klasama, to proizvodi veliki
broj vrsto vezanih klasa. Ovo je vaan problem jer neki projektni obrasci eksplicitno koriste
druge u svojim reenjima.

4.3 Primer korienja AspectJ-a u implementaciji projektnih obrazaca:


Observer obrazac
Namena Observer obrasca je da definie jedan ka vie vezu izmedju objekata tako da kada
jedan objekat promeni stanje, svi zavisni objekti budu obaveteni i aurirani automatski[3].
Objektno orjentisana implementacija Observer obrasca obino podrazumeva definisanje dodatne
promenljive u svim subjektima u kojima se uva lista Observer-a zainteresovanih za taj subjekt.
Kada subjekt eli izvestiti Observer-e o promeni stanja, poziva notify() metod, koji poziva update()
metod na svakom Observer-u u listi.

Slika 4.1: Dijagram klasa jednostavne implementacije Observer obrasca. Take, odnosno linija
imaju ulogu subjekta koje obavetavaju o svojoj promeni ekran (koji ima ulogu observera) radi
ponovnog iscrtavanja.

U sistemu pokazanom na slici, Observer obrazac je zaduen da svaka promena na subjektima


rezultira auriranjem ekrana. Kao to se vidi kd koji implementira obrazac je resejan po svim
Subject klasama. Svi uesnici (Point i Line) moraju da budu svesni svoje uloge u obrascu, tj.
sadre kd specifian za obrazac.
Neki delovi strukture Observer obrasca su zajedniki za sve instance obrasca u sistemu, dok su
neki delovi specifini za svaku instancu[3]. Delovi isti za sve instance su:
Postojanje subjekat i posmatra uloga (neke klase su
subjekti, neke posmatrai)
Odravanje veze od subjekta ka posmatrau
Opta logika auriranja (promene na subjektu iniciraju
auriranje posmatraa)
Delovi specifini za svaku instacu obrasca:
Koje klase mogu biti subjekti a koje posmatrai
Skup promena subjekta koji iniciraju promenu posmatraa
Specifian nain auriranja razliitih vrsta posmatraa
U nastavku e biti prikazan AspectJ kd na kome se moe primetiti razdvojenost ovih delova
strukture. Apstraktni aspekt enkapsulira generalizovane delove strukture obrasca, dok konkretna
implementacija aspekta brine o specifinim delovima strukture svake instance obrasca.
Primer 4.1
01 public abstract aspect ObserverProtocol {
02 protected interface Subject { }
03 protected interface Observer { }
04
05 private WeakHashMap<Subject, List<Observer>> _perSubjectObservers;
06
07 protected List<Observer> getObservers(Subject s) {
08 if (_perSubjectObservers == null) {
09 _perSubjectObservers = new WeakHashMap<Subject, List<Observer>>();
10 }
11 List<Observer> observers = _perSubjectObservers.get(s);
12 if (observers == null) {
13 observers = new LinkedList<Observer>();
14 _perSubjectObservers.put(s, observers);
15 }
16 return observers;
17 }
18 public void addObserver(Subject s,Observer o){
19 getObservers(s).add(o);
20 }
21 public void removeObserver(Subject s,Observer o){
22 getObservers(s).remove(o);
23 }
24
25 abstract protected pointcut subjectChange(Subject s);
26
27 abstract protected void updateObserver(Subject s, Observer o);
28
29 after(Subject s): subjectChange(s) {
30 for (Observer o : getObservers(s)) {
31 updateObserver(s, o);
32 }
33 }

4.3.1. Subjekat i Posmatra uloge


Uloge su realizovane preko zatienih interfejsova, nazvanih Subject i Observer (primer 4.1, linija
2-3). Interfejsi su ovde definisani pre svega da bi se omoguila njihova upotreba u kontekstu ovog
obrasca, a konkretne implementacije ObserverProtocol aspekta e dodeliti uloge odgovarajuim
klasama. Definisani su kao zatieni jer e biti korieni samo u ObserverProtocol i njegovim
konkretnim implementacijama. Ovi interfejsi su prazni (ne definiu nijednu metodu) jer obrazac ne
definie metode za uloge subjekta i posmatraa. Metode koje bi uobiajeno definisali na subjektu
i posmatrau su definisane u aspektu.

4.3.2. Subjekt-Posmatra veza


Implementacija ove veze u AspectJ kodu je lokalizovan u ObserverProtocol aspektu. Realizovan
je pomou he mape (konkretno WeakHashMap) u kojoj je mapirana lista posmatraa za svaki
subjekt. Svaka instanca obrasca je predstavljena konkretnim ObserverProtocol podaspektom, pa
e svaka instanca imati svoje subjekt-posmatra mapiranje. Promene u mapiranju se realizuju
pomou addObserver i removeObserver metoda (primer 4.1, linija 19-23). Da bi objekat O postao
posmatra subjekta S, klijent poziva ove metode na podaspektima. Na primer:

CoordinateObserving.aspectOf().addObserver(S, O);

Privatni metod getObservers() se koristi samo interno da kreira odgovarajuu strukturu podataka
(primer 4.1, linija 7-17). U ovakvoj implementaciji Observer obrasca struktura podataka koja
realizuje mapiranje izmedju subjekta i observera je centralizovano u apstraktnom aspektu. Svaka
instanca obrasca ima svoju individualnu strukturu u kojoj uva veze izmedju subjekta i observera.
Alternativa je decentralizovani pristup u kome svaki uesnik u obrascu uva svoj observere.
4.3.3 Opta logika auriranja
U ponovno upotrebljivom, apstraktnom aspektu, implementiran je samo osnovni koncept logike
auriranja, tj. subjekti mogu da se promene na takav nain da iniciraju auriranje svih njihovih
posmatraa. Ova implementacija ne definie ta ini promenu, niti na koji nain se posmatrai
auriraju. Opta logika auriranja u apstraktnom aspektu se sastoji iz tri dela[4]:
Promene od interesa sistemu se mogu posmatrati kao skup taaka u izvravanju
programa u kojima subjekat treba da aurira svoje posmatrae. Posmatrajui ovu
definiciju u kontekstu AOP-u prirodno je da se takve take odredjuju takama preseka. U
apstraktnom aspektu, znamo samo da postoje promene koje nas zanimaju, ali ne znamo
koje su to promene. Zbog toga je definisana apstraktna taka preseka subjectChange
koju treba konkretizovati u specifinoj instanci pod-aspekta (primer 4.1, linija 25).
U ponovno upotrebljivom delu implementacije takodje znamo da e posmatrai biti
aurirani ali ne moemo predvideti na koji nain e to biti uradjeno. Zbog toga je
definisana apstraktna metoda updateObserver() koja ce biti konkretizovana za svaku
instancu obrasca (primer 4.1, linija 27).
Na kraju, ponovno upotrebljiv aspekt implementira logiku auriranja koristei ve
pomenute apstraktne elemente. Ova logika je sadrana u posle savetu (primer 4.1,
linija 29-33).

4.3.4 Konkretni aspekti u Observer obrascu


Svaki konkretni aspekt definie jednu vrstu subjekt-posmatra relacije, tj. jednu instancu obrasca.
Podaspekti definiu tri stvari[4]:
Klase koje imaju uloge subjekta, odnosno posmatraa. Ovo je realizovano upotrebom
AspectJ declare parent konstrukcije koja dodaje interfejs u definiciju klase, u nameri da
dodeli ulogu toj klasi.
Definiu konceptualne operacije, koje iniciraju auriranje observera. Realizovano
konkretizacijom subjectChange take preseka.
Definiu nain na koji se auriraju posmatrai. Realizovano konkretizacijom
updateObserver() metode.

Primer 4.2
00 public aspect CoordinateObserver extends ObserverProtocol {
01 declare parents: Point implements Subject;
02 declare parents: Line implements Subject;
03 declare parents: Screen implements Observer;
04
05 protected pointcut subjectChange(Subject s):
06 (call(void Point.setX(int))
07 || call(void Point.setY(int))
08 || call(void Line.setP1(Point))
09 || call(void Line.setP2(Point)) ) && target(s);
10
11 protected void updateObserver(Subject s, Observer o) {
12 ((Screen)o).display("Coordinate change.");
13 }
14 }

4.4 Poboljanja u implementaciji projektnih obrazaca koristei AOP


Za veliki broj projektnih obrazaca, AOP implementacija se manifestovala sa nekoliko srodnih
poboljanja u modularnosti: loklizacija, ponovna upotrebljivost koda, inverzija zavisnosti,
transparentna kompozicija i jednostavno ukljuivanje obrasca [4].
Poboljanja na konkretnom primeru (Observer obrazac):
Lokalizacija koda sav kd neophodan za implementaciju Observer obrasca je izolovan
u aspektima. Klase koje uestvuju u obrascu su u potpunosti nesvesne konteksta
obrasca i kao posledicu ne postoji veza izmedju uesnika. Potencijalna promena u
obrascu je lokalizovana na jednom mestu.
Ponovna iskorienost koda Centralni deo implementacije obrasca je izvuen u
apstraktni aspekt koji je predvidjen za ponovno korienje. Za svaku instancu obrasca
potrebno je definisati konkretan podaspekt.
Transparentna kompozicija Obzirom da implementacije uesnika u obrascu nisu
vezane za obrazac, ako subjekat ili posmatra stupi u nove (viebrojne) subjekat-
posmatra odnose njihov kod se ne komplikuje i instance obrasca se ne mogu izgubiti u
kompoziciji.
Jednostavno ukljuivanje Subjekat i pasmatra nisu svesni svoje uloge u instanci
obrasca, tako da je mogue iskljuiti, odnosno ukljuiti obrazac, u sistem, bez dodatnih
promena nad uesnicima.
5. Zakljuak
Iz svega reenog u prethodnim poglavljima, izvodi se zakljuak da Aspektno Orijentisano
Programiranje, pravilnom upotrebom, moe dovesti do vee modularnosti u implementaciji
softverskih sistema. Dunost svakog modula je precizno definisana, meusobna veza je
minimalna, a evolucija sistema je olakana, svaka modifikacija ili uvoenje potpuno nove
funkcionalnosti u sistem je lokalizovano unutar jednog aspekta.
Meutim, ne treba izgubiti iz vida da sa novim nivoom apstrakcije, dolazi i vii novi kompleksnosti
sistema, za ije je razmevanje potrebno visok nivo obuke i iskustva. Preterana upotreba aspekata
u sistemu moe dovesti do toka programa koji je teko ili nemogue pratiti. Novi alati za
editovanje aspektnih jezika, debageri kojima se moe zaustaviti izvravanje programa u aspektu,
pomau u tome, ali pravilna upotreba aspekata je ipak najbolja prevencija nerazumljivih sistema.
Dodatak - Primer implementacije bankarskog sistema koristei
AOP
Nakon detaljnog opisa AOP metodologije, moemo prikazati upotrebu ovog pristupa u
implementaciji aplikacije iz svakodnevnog ivota bankarskog sistema. Usluge koje jedna banka
mora da prui svojim klijentima, ali i radnicima zaposlenim u banci, verovatno su svima poznate,
ali da nabrojimo najbitnije: povlaenje sredstava sa rauna, stavljanje sredstava na raun,
prebacivanje sredstava sa jednog na drugi raun, administracija korisnika (kreiranje, brisanje,
pregled korisnika), administracija rauna (kreranje, brisanje, suspendovanje, pregled rauna).
Naravno, u uplementaciji svake od ovih navedenih operacija, mora se voditi rauna o
isprepletanim dunostima sistema koje su od kljunog znaaja za svaki bankarski sistem:
transakcijama nad bazom podataka, sigurnosnom proverom (autorizacija korisnika), validacijom
ulaznih podataka i logovanjem svake obavljene operacije u sistemu.

D.1. Pregled reenja implementacije i korienih tehnologija


Na bankarski sistem implementiran kao primer korienja AOP-a je pojednostavljeno reenje
sistema koji bi koristile banke u realnom ivotu, gde je akcenat stavljen na implementaciju
isprepletanih dunosti sistema koristei AspectJ, ali reenje koje zadovoljava i osnovne, centralne
dunosti koje takav sistem mora da zadovolji. U datom primeru, korieni su trenutno aktuelni
principi software-skog inenjerstva: implementacija korienjem interfejsa, dependency injection,
objektno-relaciono mapiranje i troslojna apstrakcija poslovne logike domenski, DAO (Data
Access Object) i servisni sloj. Domenski objekti predstavljaju mapirane tabele (preciznije reeno
redove u tabeli) relacione baze podataka, DAO objekti definiu operacije koje se mogu izvravati
nad domenskim objektima i servis objekti definiu operacije koje su dostupne korisniku sistema i
koriste DAO objekte da bi realizovali te operacije. Kao i u mnogim aplikacijama napisanim
korenjem Java programskog jezika i srodnih tehnologija, korien je set tehnologija koji potuje
pomenute principe: Spring framework zarad bolje konfigurabilnosti i modularnosti aplikacije, JPA
(Java Persistence API) standard za objektno-relaciono mapiranje, MySQL relaciona baza za
perzistenciju podataka, Maven2 za upravljanje projektima (kompajliranje, buildovanje, pakovanje
u jar) i AspectJ za implementaciju svih sporednih dunosti sistema. Na slikama D.1.1 i D.1.2
prikazani su dijagrami klasa koje interaktuju u implementaciji dva servisa prisutna u priloenom
primeru bankarskog sistema (servis za upravljanje klijentima banke (UserService) i servis za
upravljanje raunima banke (AccountService)).
Slika D.1.1 Dijagram klasa koje uestvuju u implementaciji servisa za upravljanje klijentima
banke IUserService je interfejs koji definie operacije koje korisnik aplikacije moe izvriti nad
klijentom banke (User), UserService je konkretna implementacija tog interfejsa, IUserDao define
operacije nad domneskim objektom i UserDao je JPA/Hibernate implementacija tog interfejsa.
Slika D.1.2 Dijagram klasa koje su uestvuju u implementaciji servisa za upravljanje raunima
banke IAccountService je interfejs koji definie operacije koje korisnik aplikacije moe izvriti
nad raunima banke (Account), AccountService je abstraktna implementacija tog interfejsa koja
sadri implemnetacije operacija koje su zajednike za sve tipove rauna, dok
CheckingAccountService, SavingsAccountService i CreditAccountService sadre implementacije
operacija koje su specifine za svaku vrstu rauna (tekui, tedni i kreditni). IAccountDao define
operacije nad domenskim objektom i AccountDao je JPA/Hibernate implementacija tog interfejsa.
D.2. Implementacija kontrole pristupa (sigurnosne logike)
00 @Aspect
01 public class SecurityAspect {
02 IAuthorizationService authorizationService;
03 UserSecurityContext userSecurityContext;
04 IUserService userService;
05
06 @Before("execution(* *(..)) &&
07 @annotation(org.matf.icikic.banking.security.Secure)")
08 public void secure(JoinPoint jp) {
09 String role = null;
10 Method method = getMethod(jp);
11 Annotation[] annotations = method.getAnnotations();
12 for (int k = 0; k < annotations.length; k++) {
13 Annotation annotation = annotations[k];
14 if (annotation instanceof Secure) {
15 role=((Secure)annotation).value();
16 }
17 }
18 User target = null;
19 for (int i=0; i<jp.getArgs().length; i++) {
20 Object param = jp.getArgs()[i];
21 if (param instanceof User) {
22 target = (User) param;
23 }
24 }
25 if (target == null) {
26 for (int i=0; i<jp.getArgs().length; i++) {
27 Object param = jp.getArgs()[i];
28 if (param instanceof Account) {
29 target = userService.findUserByAccount((Account)param);
30 }
31 }
32 }
33 userSecurityContext.setTargetUser(target);
34 authorizationService.authorize(userSecurityContext, role);
35 }
36
37 protected Method getMethod(JoinPoint jp) {
38 Method invoked = null;
39 try {
40 MethodSignature met = (MethodSignature) jp.getSignature();
41 invoked = jp.getSourceLocation().getWithinType().getMethod(
42 met.getMethod().getName(),
43 met.getMethod().getParameterTypes());
44 } catch (NoSuchMethodException e) {
45 throw new RuntimeException(e);
46 }
47 return invoked;
48 }
49 }

Primer D.2.1. Aspekt koji implementira kontrolu pristupa u bankarskom sistemu

U datom primeru implementacije bankarskog sistema, kontrola pristupa je enkapsulirana u


jednom aspektu (SecurityAspect). Predstavljeni aspekt, kao i drugi aspekti iz ovog primera,
napisani su korienjem @AspectJ sintakse. Dva osnovna razloga su uticala na takvu odluku,
prvi i vaniji jeste da bi i alternativna sintaksa AspectJ-a (svi primeri do sada prikazani su
korienjem klasine AspectJ sintakse) bila predstavljena. Drugi razlog je mogunost rada sa
AspectJ korienjem obianog Java editor koda (ne postoje nove rezervisane rei, sve AspectJ
pojedinosti jezika se izraavaju pomou Java anotacija). Jedna od negativnih strana upotrebe
@AspectJ sintakse je nemogunost prosleivanja konteksta take preseka (argumenti metode,
this objekat, itd) u savet aspekta, ve se za takve potrebe mora koristiti refleksija (primer D.2.1,
linija 37-48).
Kao to je ve pomenuto u ranijem tekstu, svaki aspekt odreuju take preseka i savet koji
definie.
Aspekt iz primera D.2.1. selektuje take izvravanja svih metoda prisutnih u bankarskom sistemu
koje su oznaene sa @Secure anotacijom (primer D.2.1, linija 06-07) i umee definisan savet pre
izvravanja takve metode (@Before anotacija definie pre savet u @AspectJ sintaksi).
Sigurnosna logika implementirana u ovom primeru se zasniva na postojanju privilegija koje
korisnik mora posedovati da bi izvrio zahtevanu operaciju. Potreban nivo privilegija je definisan
unutar @Secure anotacije (primer D.2.2, linija 05, 12). Unutar saveta se definisan nivo privilegija
izvlai pomou refleksije (primer D.2.1, linija 10-17), a zatim se takoe korienjem refleksije
izvlai i User nad kojim se izvrava operacija (prosleen ili kao argument metode (primer D.2.1,
linija 18-24), ili kao vlasnik rauna koji je prosleen kao argument (primer D.2.1, linija 25-32)).
Sama autorizacija korisnika se delegira na autorizacioni servis, definisan kroz
IAuthorizationService interfejs.

01 public abstract class AccountService implements IAccountService {


02 IAccountDao accountDao;
03 IUserDao userDao;
04
05 @Secure("ROLE_ADMIN")
06 public void removeAccount(User user, Account account) {
07 user.getAccounts().remove(account);
08 userDao.saveOrUpdate(user);
09 }
10 ...
11
12 @Secure("ROLE_USER")
13 public List<Account> getAccountsForUser(User user) {
14 return accountDao.getAccountsForUser(user);
15 }

Primer D.2.2. Operacije koje zahtevaju sigurnosnu proveru pre izvravanja. Implementacija
operacije ne sadri proveru sigurnosnih pravila aplikacije, ali e potovanje tih pravila nametnuti
SecurityAspect umetanjem definisanog saveta pre izvravanja same operacije.

00 public class AuthorizationService implements IAuthorizationService {


01 public void authorize(UserSecurityContext context, String neededRole) {
02 IUserDetails details = context.getCurrentUserDetails();
03 User currUser = userDao.findUserByUsername(details.getUsername());
04 if (null == currUser) {
05 throw new SecurityException("Username '" + details.getUsername() + "'
06 not found.");
07 }
08 if(!currUser.getCredentials().getPassword().equals(details.getPassword())) {
09 throw new SecurityException("Bad password provided for username '" +
10 details.getUsername() + "'.");
11 }
12 if (neededRole.equals("ROLE_ADMIN")) {
13 if (!containsRoleByName(currUser, neededRole)) {
14 throw new SecurityException("Access denied. User [" + currUser +
15 "] has insufficient privileges.");
16 }
17 } else if (neededRole.equals("ROLE_USER")) {
18 User targetedUser = context.getTargetUser();
19 final boolean usersMatch =
targetedUser.getCredentials().getUsername().equals(currUser.getCredentials().getUser
name());
20 final boolean containsAdminRole = containsRoleByName(currUser, ROLE_ADMIN");
21 final boolean containsUserRole = containsRoleByName(currUser, "ROLE_USER");
22 if (!containsAdminRole && !(usersMatch && containsUserRole)) {
23 throw new SecurityException("Access denied. User [" + currUser +
24 "] is not matched to target user.");
25 }
26 }

Primer D.2.3. Implementacija IAuthorizationService interfejsa, servis koji enkapsulira pravila


aplikacije za davanje, odnosno zabrane pristupa trenutno ulogovanog korisnika sistema
odredjenoj operaciji sistema.
D.3. Validacija ulaznih podataka
00 @Aspect
01 public class ValidationAspect implements ApplicationContextAware {
02 ApplicationContext applicationContext;
03
04 @Before("execution(* *(..)) &&
05 @annotation(org.matf.icikic.banking.validation.Validation)")
06 public void validate(JoinPoint jp) {
07 ValidationErrors errors = new ValidationErrors();
08 Annotation[][] annotations = getMethod(jp).getParameterAnnotations();
09 for (int i = 0; i < annotations.length; i++) {
10 Annotation[] annos = annotations[i];
11 for (int j = 0; j < annos.length; j++) {
12 Annotation annotation = annos[j];
13 if (annotation instanceof ValidatorConfig) {
14 String validatorName =
15 (ValidatorConfig)annotation).validatorName();
16 IValidator validator =
17 (IValidator)applicationContext.getBean(validatorName);
18 boolean valid = validator.validate(jp.getArgs()[i], errors);
19 }
20 }
21 }
22 if (!errors.isEmpty()) {
23 throw new ValidationException(errors);
24 }
25 }
26 }
Primer D.3.1 Aspekt koji implementira validaciju podataka u bankarskom sistemu

Kao i u sluaju kontrole pristupa, validacija podataka je enkapsulirana u jednom aspektu koji
selektuje take izvravanja svih metoda u sistemu oznaenih sa @Validation anotacijom (primer
D.3.1, linija 04-05). Unutar saveta koji se umee pre izvravanja validirane metode, refleksijom se
izvlae svi parametri metode i validacija se izvrava nad onim koji su oznaeni
@ValidationConfig anotacijom (primer D.3.1, linija 08-21). U @ValidationConfig anotaciji
definisano je ime validatora koji treba primeniti na dati argument i na osnovu kojeg se sam
validator instancira iz Spring-ovog aplikacionog konteksta. Robustnost celokupnog mehanizama
validacije primenjen u primeru bankarskog sistema, zasniva se na implementaciji generikih
validatora (RequiredValidator i ConditionValidator), Spring konfiguraciji i evaluaciji OGNL (Object-
1
Graph Navigation Language) izraza, ali to prevazilazi okvire ovog poglavlja . U naem sluaju
bitno je pomenuti prisutnost validatora koji proverava da dati parametar postoji (nije null) i
validator rauna koji proverava da je raun aktivan i odredjenog tipa (tekui, tedni, kreditni).

00 public class UserService implements IUserService {


01 @Validation
02 public User saveOrUpdate(@ValidatorConfig(validatorName="requiredUser")
03 User user) {
04 return userDao.saveOrUpdate(user);
05 }
06 }
07
08 public class CheckingAccountService extends AccountService {
09 @Validation
10 public void credit(@ValidatorConfig(validatorName="activeCheckingAccount")
11 Account account, BigDecimal amount) {
12 BigDecimal balance = account.getBalance();
13 if (balance.compareTo(amount) >= 0) {
14 account.setBalance(balance.subtract(amount));
15 accountDao.save(account);
16 } else {
17 throw new InsufficientBalanceException();
18 }
19 }
20 }

1
Za bolje razumevanje implementiranog mehanizma validacije, pogledati izvorni kod bankarskog sistema
Primer D.3.2. Oznaene metode i argumenti nad kojima treba primeniti validaciju. U prvom
primeru se definie validator koji proverava prisutnost argumenta (user != null), u drugom
definisani validator proverava da li je raun aktivan i da li je tip rauna tekui.

D.4. Upravljanje transakcijama u radu sa bazom podataka


Prilikom pravljenja ovog primera bankarskog sistema, namera je bila da se predstavi nain na koji
AspectJ pomae u implementaciji isprepletanih dunosti sistema, ali i da taj sistem ima odreenu
vrednost u stvarnom ivotu, tj. da se ispotuju neki opte prihvaeni principi u izradi poslovne
aplikacije. Zbog toga, upravljanje transakcijama u naem primeru nije implementirano runo, ve
uz pomo ugraene podrke koju Spring framework nudi za upravljanje transakcijama. Spring
nudi vie razliitih naina za upravljanje transakcijama u zavisnosti od potrebnog nivoa
granularnosti i raspoloivih tehnologija; ali svi pristupi se oslanjaju na AOP metodologiju. Za nas
najzanimljiviji pristup i verovatno ve prepoznatljiv jeste postojanje @Transactional anotacije
kojom se obeleavaju metode koje treba izvriti unutar transakcije. Iako ovakav pristup deluje da
je identian ve opisanim u sluaju kontrole pristupa i validacije, Spring nudi mnogo robusnije
reenje, komercijalno prihvatljivo, ija se robusnost izraava izmeu ostalog i u mogunosti
biranja naina na koji se @Transactional anotacije obrauju. U osnovnom modu koriste se
proxy objekti kojim se okruuju metode/klase (videti poglavlju 2.5, slika 2.6), ali je mogue
specificirati AspectJ mod u kome Spring nudi AnnotationTransactionAspect koji umee kod za
upravljanje transakcijama (savet) oko oznaenih metoda. Vredno je pomenuti da se Spring kao
jedno od najee upotrebljivanih reenja u razvoju software korienjem Java tehnologija, u
velikoj meri oslanja na AOP (upravljanje transakcijama, web servisima, konfiguracija objekata,
itd), to se moe posmatrati kao priznanje elegantosti koju AOP metodologija unosi u reavanju
isprepletanih dunosti sistema.
00 public class CreditAccountService extends AccountService {
01
02 @Transactional
03 public void transfer(Account from, Account to, BigDecimal amount) {
04 credit(from, amount);
05 debit(to, amount);
06 }

Primer D.4.1. Metode koje zahtevaju izvravanje unutar transakcije. Sama metoda ne sadri kod
za upravljanje transakcijama, ali e Spring AOP umetanjem definisanog AspectJ saveta, odnosno
obmotavanjem metode u proxy objekat obezbediti izvravanje unutar transakcije.
D.5. Logovanje izvrenih operacija
00 @Aspect
01 public class LoggingAspect extends BaseBankingAspect {
02 @Pointcut("execution(* org.matf.icikic.banking.service..*(..))")
03 protected void allServiceMethods() {
04 }
05
06 @Pointcut("execution(* org.matf.icikic.banking.dao..*(..))")
07 protected void allDaoMethods() {
08 }
09
10 @Pointcut("allServiceMethods() || allDaoMethods()")
11 protected void allServiceAndDaoMethods() {
12 }
13
14 @Around("allServiceAndDaoMethods()")
15 public Object log(ProceedingJoinPoint pjp) throws Throwable {
16 Logger logger = LoggerFactory.getLogger(getTypeName(pjp));
17 try {
18 boolean isDebugEnabled = logger.isDebugEnabled();
19 if (isDebugEnabled) {
20 logger.debug(getOperationName(pjp)
21 + "( --> " + getArgs(pjp) + ")");
22 }
23 long start = System.nanoTime();
24 Object ret = pjp.proceed();
25 long end = System.nanoTime();
26 if (isDebugEnabled) {
27 double execTime = (end - start) / 1000;
28 logger.debug(getOperationName(pjp) + "( <-- " +
29 formatString(ret) + ") , execution time: " + execTime+ " ms");
30 }
31 return ret;
32 } catch (Throwable e) {
33 if (logger.isErrorEnabled()) {
34 logger.error(getOperationName(pjp) + "( <-- ) : "
35 + e.getLocalizedMessage(), e);
36 }
37 throw e;
38 }
39 }
40 }

Primer D.5.1. Aspekt za logovanje i prenje performansi sistema

Aspekt za logovanje se razlikuje od prehodno prikazanih u par taaka. On definie imenovane


take preseka (allServiceMethods i allDaoMethods) i primenjuje okruujui savet oko svake
metode u svakoj klasi u org.matf.icikic.banking.dao i org.matf.icikic.banking.service paketu. Pre
ulaska u svaku operaciju, ime operacije i prosleeni argumenti se loguju. Nakon zavretka
operacije, loguju se rezultat i vreme izvravanja, odnosno greka u sluaju da operacija nije
uspela.
Reference

Knjige i lanci

[1] Bauer, C., King, . Java Persistence with Hibernate, Manning Publications, 2005.
[2] Florijn, G., Meijers, M., Winsen, P. van. Tool support for object-oriented patterns. Objavljeno u
Proceedings of ECOOP, 1997.
[3] Gamma, E., Helm, R., Johnson R., Vlissides J. Design Patterns-Elements of Reusable Object-
Oriented Software. Addison-Wesley, 1994.
[4] Hannemann, J., Kiczales, G. Design Pattern Implementation in Java and AspectJ. Objavljeno
th
u Proceedings of the 17 Annual ACM Conference on Object-Oriented Programming, Systems,
Languages, and Applications (OOPSLA), strana 161-73, 2002.
[5] Laddad, R. AspectJ in Action, drugo izdanje. Manning Publications, 2008.
[6] Mapelsden, D., Hosking, J. and Grundy, J. Design Pattern Modelling and Instantiation using
DPML. Objavljeno u Proceeding of TOOLS Pacific, 2002.
[7] Norvig, P. Design Patterns in Dynamic Programming. Objavljeno u Object World, Boston MA,
1996.
[8] Sullivan, G. T. Advanced Programming Language Features for Executable Design Patterns.
MIT Artificial Intelligence Laboratory, 2002.
[9] Walls, C., Breidenbach, R.. Spring in Action, drugo izdanje. Manning Publications, 2008.

Internet resorsi
[10] Martin, Robert C. The Open Closed Principle, 2002. Dostupno na
http://www.objectmentor.com/resources/articles/ocp.pdf.
[11] Martin, Robert C. The Single Responsibility Principle, 2002. Dostupno na
http://www.objectmentor.com/resources/articles/ocp.pdf.
[11] Aspektno orijentisano programiranja http://aosd.net
[12] AspectJ http://www.eclipse.org/aspectj/
[13] Spring framework http://www.springframework.org/
[14] Separation of Concerns http://ctrl-shift-b.blogspot.com/2008/01/art-of-separation-of-
concerns.html
[15] On the role of scientific thought (E.W.Dijsktra)
http://www.cs.utexas.edu/users/EWD/transcriptions/EWD04xx/EWD447.html

You might also like