Implementácia vlastnej jarnej anotácie AOP

1. Úvod

V tomto článku implementujeme vlastnú anotáciu AOP pomocou podpory AOP na jar.

Najskôr poskytneme prehľad AOP na vysokej úrovni s vysvetlením, čo to je a aké sú jeho výhody. Potom budeme krok za krokom implementovať našu anotáciu a postupne budeme postupne budovať hlbšie pochopenie konceptov AOP.

Výsledkom bude lepšie pochopenie AOP a schopnosť vytvárať v budúcnosti naše vlastné jarné anotácie.

2. Čo je anotácia AOP?

Aby sme to rýchlo zhrnuli, AOP znamená aspektovo orientované programovanie. V podstate je to spôsob pridania správania k existujúcemu kódu bez úpravy tohto kódu.

Podrobný úvod do AOP obsahuje články o bodových rezoch AOP a radách. Tento článok predpokladá, že už máme základné vedomosti.

Typ AOP, ktorý budeme v tomto článku implementovať, je založený na anotáciách. Možno to už poznáme, ak sme použili jar @ Transakčné anotácia:

@Transactional public void orderGoods (objednávka objednávky) {// Séria databázových volaní, ktoré sa majú vykonať v transakcii}

Kľúčová je tu neinvazívnosť. Použitím metadát anotácie nie je naša hlavná obchodná logika znečistená naším kódom transakcie. Vďaka tomu je jednoduchšie uvažovať, refaktorovať a testovať izolovane.

Ľudia, ktorí vyvíjajú jarné aplikácie, to niekedy môžu vidieť akoSpring Magic “, bez toho, aby som veľmi premýšľal o tom, ako to funguje. V skutočnosti to, čo sa deje, nie je nijako zvlášť komplikované. Po dokončení krokov v tomto článku však budeme môcť vytvoriť svoju vlastnú anotáciu, aby sme porozumeli a využili AOP.

3. Maven závislosť

Najskôr pridajme naše závislosti Maven.

V tomto príklade budeme používať Spring Boot, pretože jeho prístup ku konvencii cez konfiguráciu nám umožňuje rozbehnúť sa čo najrýchlejšie:

 org.springframework.boot spring-boot-starter-parent 2.2.2.RELEASE org.springframework.boot spring-boot-starter-aop 

Upozorňujeme, že sme zahrnuli štartér AOP, ktorý vťahuje do knižníc, ktoré potrebujeme na začatie implementácie aspektov.

4. Vytvorenie vlastnej poznámky

Anotácia, ktorú vytvoríme, je taká, ktorá sa použije na zaznamenanie času, ktorý trvá vykonanie metódy. Vytvorme našu anotáciu:

@Target (ElementType.METHOD) @Retention (RetentionPolicy.RUNTIME) public @interface LogExecutionTime {} 

Aj keď je to pomerne jednoduchá implementácia, stojí za zmienku, na čo sa tieto dve meta-anotácie používajú.

The @ Cieľ anotácia nám hovorí, kde bude naša anotácia použiteľná. Tu používame ElementType.Method, čo znamená, že to bude fungovať iba na metódach. Ak by sme sa pokúsili použiť anotáciu kdekoľvek inde, potom by sa náš kód nepodarilo zostaviť. Toto správanie má zmysel, pretože naša anotácia sa použije na čas vykonania metódy protokolovania.

A @ Zadržanie iba uvádza, či bude anotácia k dispozícii JVM za behu alebo nie. V predvolenom nastavení nie je, takže Spring AOP by anotáciu nevidel. Preto to bolo prekonfigurované.

5. Tvorba nášho aspektu

Teraz máme našu anotáciu, vytvorme si náš aspekt. Toto je iba modul, ktorý zapuzdrí náš prierezový problém, ktorým je v našom prípade protokolovanie času vykonania metódy. Všetko, čo to je, je trieda s poznámkami @Aspect:

@Aspect @Component verejná trieda ExampleAspect {}

Zahrnuli sme tiež @ Komponent anotácia, pretože naša trieda musí tiež byť jarnou fazuľou, aby bola detekovaná. V podstate sa jedná o triedu, kde budeme implementovať logiku, ktorú chceme vložiť do svojej vlastnej anotácie.

6. Vytvorenie nášho bodu a rady

Poďme si teraz vytvoriť bod a radu. Pôjde o komentovanú metódu, ktorá žije v našom aspekte:

@Around ("@ annotation (LogExecutionTime)") verejný objekt logExecutionTime (ProceedingJoinPoint joinPoint) hodí Throwable {return joinPoint.proceed (); }

Technicky to zatiaľ nič nezmení na správaní, ale stále je toho dosť, čo si vyžaduje analýzu.

Najskôr sme našu metódu anotovali pomocou @Okolo. Toto je naša rada a ďalšia rada znamená, že pridávame ďalší kód pred aj po vykonaní metódy. Existujú aj iné druhy rád, ako napr predtým a po budú však mimo rozsahu pôsobnosti tohto článku.

Ďalej náš @Okolo anotácia má argument point cut. Náš pointcut iba hovorí: „Použite túto radu na ľubovoľnú metódu s poznámkami @LogExecutionTime. “ Existuje mnoho ďalších typov bodových výrezov, ale v prípade rozsahu budú opäť vynechané.

Metóda logExecutionTime () samotná je naša rada. Existuje jediný argument, ProceedingJoinPoint. V našom prípade to bude vykonávacia metóda, ktorá bola anotovaná @LogExecutionTime.

Nakoniec, keď sa zavolá naša anotovaná metóda, bude sa volať najskôr naša rada. Potom je na našej rade rozhodnúť sa, čo ďalej. V našom prípade naša rada nerobí nič iné ako volanie pokračovať (), čo je práve volanie pôvodnej anotovanej metódy.

7. Zaznamenávanie nášho času vykonania

Teraz máme svoju kostru na svojom mieste, všetko, čo musíme urobiť, je pridať do našich rád nejakú logiku navyše. Toto bude to, čo okrem volania pôvodnej metódy zaznamená čas vykonania. Pridajme si k svojej práci toto správanie navyše:

@Around ("@ annotation (LogExecutionTime)") verejný objekt logExecutionTime (ProceedingJoinPoint joinPoint) hodí Throwable {long start = System.currentTimeMillis (); Objekt pokračovať = joinPoint.proceed (); long executionTime = System.currentTimeMillis () - štart; System.out.println (joinPoint.getSignature () + "vykonaný v" + executionTime + "ms"); návrat pokračovať; }

Tu sme opäť neurobili nič, čo by bolo obzvlášť komplikované. Práve sme zaznamenali aktuálny čas, vykonali metódu a potom vytlačili čas, ktorý trval konzolu. Taktiež zaznamenávame podpis metódy, ktorá sa poskytuje na použitie súboru joinpoint inštancia. Ak by sme chceli, mohli by sme tiež získať prístup k ďalším bitom informácií, napríklad k argumentom metódy.

Teraz skúsme anotovať metódu pomocou @LogExecutionTime, a potom ich vykonaním zistiť, čo sa stane. Upozorňujeme, že to musí byť Spring Bean, aby fungoval správne:

@LogExecutionTime public void serve () hodí InterruptedException {Thread.sleep (2000); }

Po vykonaní by sa nám na konzole malo zobraziť nasledujúce:

void org.baeldung.Service.serve () vykonaný o 2030ms

8. Záver

V tomto článku sme využili Spring Boot AOP na vytvorenie našej vlastnej anotácie, ktorú môžeme použiť na fazuľa Spring, aby sme im za behu poskytli ďalšie správanie.

Zdrojový kód našej aplikácie je k dispozícii na stránkach GitHub; toto je projekt Maven, ktorý by mal byť schopný bežať tak, ako je.


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