Uspoređujući Spring AOP i AspectJ

1. Uvod

Danas postoji više dostupnih AOP knjižnica i one trebaju odgovoriti na brojna pitanja:

  • Je li kompatibilan s mojom postojećom ili novom aplikacijom?
  • Gdje mogu primijeniti AOP?
  • Koliko brzo će se integrirati s mojom aplikacijom?
  • Kolika je režija izvedbe?

U ovom ćemo članku pogledati odgovore na ova pitanja i predstaviti Spring AOP i AspectJ - dva najpopularnija AOP okvira za Javu.

2. Koncepti AOP-a

Prije nego što započnemo, napravimo brzi pregled pojmova i temeljnih koncepata na visokoj razini:

  • Aspekt - standardni kôd / značajka koji je raštrkan na više mjesta u aplikaciji i obično se razlikuje od stvarne poslovne logike (na primjer, upravljanje transakcijama). Svaki se aspekt usredotočuje na određenu presječnu funkcionalnost
  • Točka spajanja - to je određena točka tijekom izvršavanja programa poput izvršavanja metode, poziva konstruktora ili dodjele polja
  • Savjet - radnja koju aspekt poduzima u određenoj točki spajanja
  • Pointcut - regularni izraz koji odgovara točki spajanja. Svaki put kad se bilo koja točka pridruživanja podudara s odrezivanjem točke, izvršava se određeni savjet povezan s tim odsječkom
  • Tkanje - postupak povezivanja aspekata s ciljanim objektima radi stvaranja savjetovanog objekta

3. Proljetni AOP i AspectJ

Sada, razgovarajmo o proljetnom AOP-u i AspectJ-u na više osi - poput sposobnosti, ciljeva, tkanja, unutarnje strukture, spojnih točaka i jednostavnosti.

3.1. Sposobnosti i ciljevi

Jednostavno rečeno, Spring AOP i AspectJ imaju različite ciljeve.

Spring AOP ima za cilj pružiti jednostavnu implementaciju AOP-a u Spring IoC za rješavanje najčešćih problema s kojima se programeri susreću. Nije zamišljen kao cjelovito AOP rješenje - može se primijeniti samo na grah kojim upravlja proljetni spremnik.

S druge strane, AspectJ je izvorna AOP tehnologija kojoj je cilj pružiti cjelovito AOP rješenje. Robusniji je, ali i znatno kompliciraniji od proljetnog AOP-a. Također je vrijedno napomenuti da se AspectJ može primijeniti na sve objekte domene.

3.2. Tkanje

I AspectJ i Spring AOP koriste različitu vrstu tkanja koja utječe na njihovo ponašanje u pogledu performansi i jednostavnosti upotrebe.

AspectJ koristi tri različite vrste tkanja:

  1. Kompilacijsko tkanje: Kompajler AspectJ uzima kao ulazni izvor i izvorni kod našeg aspekta i našu aplikaciju i kao rezultat daje tkane datoteke klase
  2. Tkanje nakon sastavljanja: Ovo je također poznato kao binarno tkanje. Koristi se za tkanje postojećih datoteka klase i JAR datoteka s našim aspektima
  3. Tkanje tijekom opterećenja: To je točno kao nekadašnje binarno tkanje, s tom razlikom što se tkanje odgađa dok učitavač klasa ne učita datoteke klase u JVM

Za detaljnije informacije o samom AspectJ-u, prijeđite na ovaj članak.

Kako AspectJ koristi vrijeme kompajliranja i tkanje vremena učitavanja, Proljetni AOP koristi se tijekom izvođenja tkanja.

Kod runtime tkanja, aspekti se tkaju tijekom izvršavanja aplikacije koristeći proxyje ciljanog objekta - koristeći ili JDK dinamički proxy ili CGLIB proxy (o čemu će se raspravljati u sljedećoj točki):

3.3. Unutarnja struktura i primjena

Spring AOP je AOP okvir zasnovan na proxyju. To znači da će za implementaciju aspekata na ciljne objekte stvoriti proxyje tog objekta. To se postiže na jedan od dva načina:

  1. JDK dinamički proxy - preferirani način za proljetni AOP. Kad god ciljani objekt implementira čak i jedno sučelje, tada će se koristiti JDK dinamički proxy
  2. CGLIB proxy - ako ciljni objekt ne implementira sučelje, tada se može koristiti CGLIB proxy

Više o mehanizmima proxy proljetnog AOP-a možemo saznati iz službenih dokumenata.

AspectJ, s druge strane, ne radi ništa u vrijeme izvođenja jer se klase kompajliraju izravno s aspektima.

I tako za razliku od Spring AOP-a, ne zahtijeva nikakve uzorke dizajna. Da bi utkao aspekte koda, on uvodi svoj kompajler poznat pod nazivom AspectJ compiler (ajc), kroz koji mi kompajliramo svoj program i zatim ga pokrećemo isporučujući malu (<100K) runtime knjižnicu.

3.4. Točke spajanja

U odjeljku 3.3 pokazali smo da se Spring AOP temelji na proxy uzorcima. Zbog toga treba podrazvrstati ciljanu klasu Java i u skladu s tim primijeniti unakrsne probleme.

Ali dolazi s ograničenjem. Ne možemo primijeniti unakrsne brige (ili aspekte) na klase koje su „konačne“, jer ih se ne može nadjačati, što bi rezultiralo iznimkom u izvođenju.

Isto vrijedi i za statičke i završne metode. Proljetni aspekti se na njih ne mogu primijeniti jer ih se ne može nadjačati. Stoga Spring AOP zbog ovih ograničenja podržava samo točke spajanja izvršavanja metode.

Međutim, AspectJ upleće međusobne brige izravno u stvarni kod prije izvođenja. Za razliku od Spring AOP-a, on ne zahtijeva potklasiranje ciljanog objekta, a time podržava i mnoge druge točke pridruživanja. Slijedi sažetak podržanih točaka spajanja:

Točka spajanjaPodržani proljetni AOPPodržani aspektJ
Poziv metodeNeDa
Izvršenje metodeDaDa
Poziv konstruktoraNeDa
Izvršenje konstruktoraNeDa
Izvođenje statičkog inicijalizatoraNeDa
Inicijalizacija objektaNeDa
Referenca na terenuNeDa
Terenski zadatakNeDa
Izvršenje rukovateljaNeDa
Izvršenje savjetaNeDa

Također je vrijedno napomenuti da se u proljetnom AOP-u aspekti ne primjenjuju na metodu pozvanu u istoj klasi.

To je očito jer kad pozivamo metodu unutar iste klase, tada ne pozivamo metodu proxyja koju pruža Spring AOP. Ako nam je potrebna ova funkcionalnost, tada moramo definirati zasebnu metodu u različitim grahovima ili koristiti AspectJ.

3.5. Jednostavnost

Proljetni AOP je očito jednostavniji jer ne uvodi dodatni kompajler ili tkač između našeg procesa izrade. Koristi runtving tkanje i stoga se neprimjetno integrira s našim uobičajenim postupkom izrade. Iako izgleda jednostavno, radi samo s grahom kojim upravlja Proljeće.

Međutim, da bismo koristili AspectJ, dužni smo predstaviti kompajler AspectJ (ajc) i ponovno upakirati sve naše knjižnice (osim ako se ne prebacimo na naknadno kompajliranje ili tkanje tijekom učitavanja).

Ovo je, naravno, složenije od prethodnog - jer uvodi AspectJ Java Tools (koji uključuje kompajler (ajc), program za ispravljanje pogrešaka (ajdb), generator dokumentacije (ajdoc), preglednik programske strukture (ajbrowser)) koji mi trebate se integrirati s našim IDE-om ili alatom za izgradnju.

3.6. Izvođenje

Što se tiče izvedbe, tkanje tijekom sastavljanja mnogo je brže od runtime tkanja. Spring AOP je okvir zasnovan na proxyju, pa postoji stvaranje proxyja u vrijeme pokretanja aplikacije. Također, postoji još nekoliko poziva metoda po aspektu, što negativno utječe na izvedbu.

S druge strane, AspectJ uvrštava aspekte u glavni kôd prije nego što se aplikacija izvrši, pa stoga nema dodatnih dodatnih troškova, za razliku od Spring AOP-a.

Iz tih razloga mjerila sugeriraju da je AspectJ gotovo otprilike 8 do 35 puta brži od proljetnog AOP-a.

4. Sažetak

Ova brza tablica sažima ključne razlike između Spring AOP i AspectJ:

Proljetni AOPAspektJ
Implementirano u čistoj JaviProvedeno pomoću ekstenzija programskog jezika Java
Nema potrebe za odvojenim postupkom sastavljanjaPotreban je kompajler AspectJ (ajc) ako LTW nije postavljen
Dostupno je samo vrijeme izvođenja tkanjaVreme izvođenja tkanja nije dostupno. Podržava tkanje tijekom vremena prevođenja, naknadnog prevođenja i učitavanja
Manje snažno - podržava samo tkanje na razini metodeMoćnije - može tkati polja, metode, konstruktore, statičke inicijalizatore, konačnu klasu / metode itd.
Može se implementirati samo na grahu kojim upravlja Spring SpringMože se implementirati na svim objektima domene
Podržava samo izrezivanja izvršavanja metodePodržite sve točke
Proxyji se stvaraju ciljanih objekata i aspekti se primjenjuju na tim proxyjimaAspekti su utkani izravno u kôd prije izvršavanja aplikacije (prije izvođenja)
Mnogo sporije od AspectJBolja izvedba
Jednostavno naučiti i primijenitiUsporedno složeniji od proljetnog AOP-a

5. Odabir pravog okvira

Ako analiziramo sve argumente iznesene u ovom odjeljku, počet ćemo shvaćati da uopće nije jedan okvir bolji od drugog.

Jednostavno rečeno, izbor uvelike ovisi o našim zahtjevima:

  • Okvir: Ako aplikacija ne koristi Spring framework, onda nemamo druge mogućnosti nego odustati od ideje o korištenju Spring AOP-a jer ne može upravljati ničim što je izvan dosega proljetnog spremnika. Međutim, ako je naša aplikacija u potpunosti izrađena pomoću Spring framework-a, tada možemo koristiti Spring AOP jer je jednostavno naučiti i primijeniti se
  • Fleksibilnost: S obzirom na ograničenu podršku za točke pridruživanja, Spring AOP nije cjelovito AOP rješenje, ali rješava najčešće probleme s kojima se programeri susreću. Iako ako želimo dublje iskopati i iskoristiti AOP do maksimuma i želimo podršku iz širokog raspona dostupnih točaka spajanja, AspectJ je izbor
  • Izvedba: Ako koristimo ograničene aspekte, tada postoje trivijalne razlike u izvedbi. Ali ponekad postoje slučajevi kada aplikacija ima više od desetaka tisuća aspekata. U takvim slučajevima ne bismo željeli koristiti runtving tkanje, pa bi bilo bolje odlučiti se za AspectJ. Poznato je da je AspectJ 8 do 35 puta brži od proljetnog AOP-a
  • Najbolje od oboje: oba su okvira u potpunosti međusobno kompatibilna. Uvijek možemo iskoristiti Spring AOP kad god je to moguće i dalje koristiti AspectJ za dobivanje podrške za točke pridruživanja koje prethodni ne podržavaju

6. Zaključak

U ovom smo članku analizirali proljetni AOP i AspectJ na nekoliko ključnih područja.

Usporedili smo dva pristupa AOP-u, kako po fleksibilnosti, tako i po tome koliko će se lako uklopiti u našu aplikaciju.


$config[zx-auto] not found$config[zx-overlay] not found