Porovnávanie jarných AOP a AspectJ

1. Úvod

V súčasnosti existuje viac dostupných knižníc AOP, ktoré musia byť schopné odpovedať na niekoľko otázok:

  • Je kompatibilný s mojou existujúcou alebo novou aplikáciou?
  • Kde môžem implementovať AOP?
  • Ako rýchlo sa integruje do mojej aplikácie?
  • Aká je réžia výkonu?

V tomto článku sa pozrieme na odpovede na tieto otázky a predstavíme si Spring AOP a AspectJ - dva najpopulárnejšie rámce AOP pre Javu.

2. Koncepty AOP

Než začneme, urobme si rýchlu kontrolu pojmov a základných pojmov na vysokej úrovni:

  • Pomer strán - štandardný kód / funkcia, ktorá je rozptýlená na viacerých miestach v aplikácii a zvyčajne sa líši od skutočnej obchodnej logiky (napríklad Správa transakcií). Každý aspekt sa zameriava na konkrétnu prierezovú funkcionalitu
  • Pripojovací bod - je to konkrétny bod počas vykonávania programov, ako je vykonávanie metódy, volanie konštruktora alebo priradenie poľa
  • Rada - akcia vykonaná aspektom v konkrétnom spojovacom bode
  • Bodový bod - regulárny výraz, ktorý sa zhoduje s bodom spojenia. Zakaždým, keď sa ktorýkoľvek bod spojenia zhoduje s bodom, vykoná sa špecifikovaná rada spojená s týmto bodom
  • Tkanie - proces prepájania aspektov s cieľovými objektmi za účelom vytvorenia odporúčaného objektu

3. Jarné AOP a AspectJ

Teraz poďme diskutovať o Spring AOP a AspectJ naprieč mnohými osami - ako sú schopnosti, ciele, tkanie, vnútorná štruktúra, spojovacie body a jednoduchosť.

3.1. Schopnosti a ciele

Jednoducho povedané, jarné AOP a AspectJ majú odlišné ciele.

Cieľom jarného AOP je poskytnúť jednoduchú implementáciu AOP v rámci jarného IoC na riešenie najbežnejších problémov, ktorým programátori čelia. Nie je to zamýšľané ako úplné riešenie AOP - je možné ho použiť iba na fazuľu, ktorá je spravovaná nádobou Spring.

Na druhej strane, AspectJ je pôvodná technológia AOP, ktorej cieľom je poskytnúť úplné riešenie AOP. Je robustnejší, ale tiež podstatne komplikovanejší ako Spring AOP. Je tiež potrebné poznamenať, že AspectJ je možné použiť na všetky objekty domény.

3.2. Tkanie

AspectJ aj Spring AOP používajú odlišný typ tkania, ktorý ovplyvňuje ich správanie, pokiaľ ide o výkon a jednoduché použitie.

AspectJ využíva tri rôzne typy tkania:

  1. Tkanie v čase kompilácie: Kompilátor AspectJ berie ako vstup zdrojový kód nášho aspektu aj našej aplikácie a vytvára výstupné súbory triedy tkané ako výstup
  2. Postkompilované tkanie: Toto je tiež známe ako binárne tkanie. Používa sa na tkanie existujúcich súborov triedy a súborov JAR s našimi aspektmi
  3. Tkanie času načítania: Je to presne také isté ako predchádzajúce binárne tkanie, s tým rozdielom, že tkanie sa odkladá, kým nakladač tried nenačíta súbory triedy do JVM.

Podrobnejšie informácie o aspekte samotnom nájdete v tomto článku.

Pretože AspectJ používa tkanie času kompilácie a času načítania, Jarná AOP využíva runtime tkanie.

Pri runtime tkaní sú aspekty utkané počas vykonávania aplikácie pomocou proxy cieľového objektu - pomocou dynamického proxy JDK alebo CGLIB proxy (o ktorých sa pojednáva v ďalšom bode):

3.3. Vnútorná štruktúra a použitie

Jarný AOP je rámec AOP založený na proxy serveri. To znamená, že na implementáciu aspektov do cieľových objektov sa vytvoria proxy tohto objektu. To sa dá dosiahnuť jedným z dvoch spôsobov:

  1. JDK dynamic proxy - preferovaný spôsob pre Spring AOP. Kedykoľvek cieľový objekt implementuje čo i len jedno rozhranie, použije sa dynamický proxy server JDK
  2. CGLIB proxy - ak cieľový objekt neimplementuje rozhranie, je možné použiť CGLIB proxy

Viac informácií o mechanizmoch proxy servera AOP na jar sa môžeme dozvedieť z oficiálnych dokumentov.

AspectJ, na druhej strane, za behu nerobí nič, pretože triedy sú kompilované priamo s aspektmi.

A tak na rozdiel od jarného AOP nevyžaduje žiadne dizajnové vzory. Na prepojenie aspektov s kódom predstavuje svoj kompilátor známy ako kompilátor AspectJ (ajc), prostredníctvom ktorého kompilujeme náš program a potom ho spustíme zadaním malej (<100 kB) runtime knižnice.

3.4. Spojovacie body

V časti 3.3 sme ukázali, že jarný AOP je založený na proxy vzoroch. Z tohto dôvodu potrebuje podtriedu cieľovej triedy Java a zodpovedajúce uplatnenie prierezových problémov.

Prichádza však s obmedzením. Nemôžeme aplikovať prierezové záujmy (alebo aspekty) na triedy, ktoré sú „konečné“, pretože ich nemožno prepísať, a preto by to malo za následok výnimku za behu.

To isté platí pre statické a konečné metódy. Jarné aspekty sa na ne nemôžu vzťahovať, pretože ich nemožno prekonať. Preto Spring AOP z dôvodu týchto obmedzení podporuje iba spojovacie body vykonania metódy.

Avšak AspectJ zapája prierezové obavy priamo do skutočného kódu pred spustením. Na rozdiel od Spring AOP nevyžaduje podtriedu cieľového objektu, a teda podporuje aj mnoho ďalších spojovacích bodov. Nasleduje zoznam podporovaných spojovacích bodov:

JoinpointJarný AOP podporovanýAspectJ Podporované
Method CallNieÁno
Vykonanie metódyÁnoÁno
Výzva konštruktéraNieÁno
Konštruktor PopravaNieÁno
Statické spustenie inicializátoraNieÁno
Inicializácia objektuNieÁno
Referenčné poleNieÁno
Priradenie poľaNieÁno
Vykonávanie psovodaNieÁno
Vykonávanie rádNieÁno

Je tiež potrebné poznamenať, že na jar AOP sa aspekty neuplatňujú na metódu nazývanú v rámci tej istej triedy.

Je to zjavne preto, že keď voláme metódu v rámci tej istej triedy, nevoláme metódu proxy, ktorú poskytuje Spring AOP. Ak potrebujeme túto funkcionalitu, musíme definovať samostatnú metódu v rôznych fazuliach alebo použiť AspectJ.

3.5. Jednoduchosť

Jarný AOP je zjavne jednoduchší, pretože medzi našim procesom vytvárania nezavádza žiadny ďalší kompilátor alebo tkáč. Používa runtime tkanie, a preto sa bezproblémovo integruje do nášho obvyklého procesu zostavovania. Aj keď to vyzerá jednoducho, funguje to iba s fazuľami, ktoré spravuje jar.

Ak však chcete používať AspectJ, je potrebné predstaviť kompilátor AspectJ (ajc) a znovu zabaliť všetky naše knižnice (pokiaľ neprepneme na tkanie po kompilácii alebo načítaní).

To je samozrejme komplikovanejšie ako to prvé - pretože predstavuje AspectJ Java Tools (ktoré zahŕňajú kompilátor (ajc), debugger (ajdb), generátor dokumentácie (ajdoc), prehliadač programovej štruktúry (ajbrowser)), ktorý musíte sa integrovať buď s našim IDE, alebo s nástrojom na zostavenie.

3.6. Výkon

Čo sa týka výkonu, tkanie v kompilácii je oveľa rýchlejšie ako tkanie za behu. Jarný AOP je rámec založený na proxy, takže pri spustení aplikácie dochádza k vytváraniu proxy. Existuje tiež niekoľko ďalších vyvolaných metód pre každý aspekt, čo negatívne ovplyvňuje výkon.

Na druhej strane AspectJ zapája aspekty do hlavného kódu pred vykonaním aplikácie, a teda na rozdiel od Spring AOP neexistuje žiadna ďalšia runtime réžia.

Z týchto dôvodov referenčné hodnoty naznačujú, že AspectJ je takmer približne 8 až 35-krát rýchlejší ako jarný AOP.

4. Zhrnutie

Táto rýchla tabuľka sumarizuje kľúčové rozdiely medzi Spring AOP a AspectJ:

Jarný AOPAspektJ
Implementované v čistej JaveImplementované pomocou rozšírení programovacieho jazyka Java
Nie je potrebný samostatný proces kompiláciePotrebuje kompilátor AspectJ (ajc), pokiaľ nie je nastavený LTW
K dispozícii je iba tkanie za behuRuntime tkanie nie je k dispozícii. Podporuje tkanie v čase kompilácie, po kompilácii a načítaní
Menej výkonný - podporuje iba tkanie na úrovni metódVýkonnejšie - dokáže tkať polia, metódy, konštruktory, statické inicializátory, výslednú triedu / metódy atď ...
Dá sa implementovať iba na fazuľa spravovaná kontajnerom SpringMožno implementovať na všetky objekty domény
Podporuje iba bodové body vykonania metódyPodpora všetkých bodových výrezov
Proxy sú vytvorené z cieľových objektov a na tieto proxy sú aplikované aspektyAspekty sú votkané priamo do kódu pred spustením aplikácie (pred spustením)
Oveľa pomalšie ako AspectJLepší výkon
Ľahko sa učia a uplatňujúPomerne komplikovanejšie ako Spring AOP

5. Výber správneho rámca

Ak analyzujeme všetky argumenty uvedené v tejto časti, začneme chápať, že vôbec nie je to, že jeden rámec je lepší ako iný.

Jednoducho povedané, výber silno závisí od našich požiadaviek:

  • Rámec: Ak aplikácia nepoužíva jarný rámec, nemáme inú možnosť, ako upustiť od myšlienky používať Spring AOP, pretože nedokáže spravovať nič, čo je mimo dosahu jarného kontajnera. Ak je však naša aplikácia vytvorená úplne pomocou jarného rámca, môžeme použiť jarný AOP, pretože je jednoduché sa ho učiť a aplikovať
  • Flexibilita: Vzhľadom na obmedzenú podporu joinpoint nie je Spring AOP úplným riešením AOP, ale rieši najbežnejšie problémy, ktorým programátori čelia. Aj keď, ak sa chceme hlbšie zaoberať a využívať AOP na svoje maximálne možnosti a chceme podporu zo širokej škály dostupných spojovacích bodov, potom je voľbou AspectJ
  • Výkon: Ak používame obmedzené aspekty, potom existujú triviálne rozdiely vo výkonnosti. Ale niekedy existujú prípady, keď aplikácia má viac ako desaťtisíce aspektov. V takýchto prípadoch by sme nechceli používať runtime tkanie, takže by bolo lepšie zvoliť AspectJ. Je známe, že AspectJ je 8 až 35-krát rýchlejší ako jarný AOP
  • Najlepšie z oboch: Oba tieto rámce sú navzájom úplne kompatibilné. Vždy, keď je to možné, môžeme využiť výhody jarného AOP a stále používať AspectJ na získanie podpory spojovacích bodov, ktoré bývalý nepodporuje

6. Záver

V tomto článku sme analyzovali jarné AOP aj AspectJ v niekoľkých kľúčových oblastiach.

Porovnali sme dva prístupy k AOP z hľadiska flexibility, ako aj toho, ako ľahko sa zmestia do našej aplikácie.


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