CDI Interceptor vs Spring Aspect J.

1. Úvod

Vzor zachytávača sa všeobecne používa na pridanie novej prierezovej funkčnosti alebo logiky do aplikácie a má pevnú podporu vo veľkom počte knižníc.

V tomto článku sa budeme venovať a porovnávať dve z týchto hlavných knižníc: zachytávače CDI a Spring AspectJ.

2. Nastavenie projektu zachytávača CDI

CDI je oficiálne podporovaná pre Jakarta EE, ale niektoré implementácie poskytujú podporu pre použitie CDI v prostredí Java SE. Weld možno považovať za jeden príklad implementácie CDI, ktorá je podporovaná v prostredí Java SE.

Aby sme mohli používať CDI, musíme importovať knižnicu Weld do nášho POM:

 org.jboss.weld.se weld-se-core 3.0.5.Final 

Najnovšiu knižnicu Weld nájdete v úložisku Maven.

Vytvorme teraz jednoduchý zachytávač.

3. Predstavujeme CDI Interceptor

Aby sme mohli určiť triedy, ktoré sme potrebovali zachytiť, vytvorme väzbu zachytávača:

@InterceptorBinding @Target ({METHOD, TYPE}) @Retention (RUNTIME) public @interface Audited {}

Po definovaní väzby zachytávača musíme definovať skutočnú implementáciu zachytávača:

@Audited @Interceptor verejná trieda AuditedInterceptor {public static boolean calledBefore = false; public static boolean calledAfter = false; @AroundInvoke public Object auditMethod (InvocationContext ctx) vyvolá výnimku {calledBefore = true; Výsledok objektu = ctx.proceed (); calledAfter = true; návratový výsledok; }}

Každý @AroundInvoke metóda vyžaduje a javax.interceptor.InvocationContext argument, vráti a java.lang.Objekt, a môže hodiť Výnimka.

A tak, keď anotujeme metódu novým @Audit rozhranie, metóda auditu najskôr sa vyvolá a až potom bude prebiehať aj cieľová metóda.

4. Použite zachytávač CDI

Použijme vytvorený zachytávač na nejakú obchodnú logiku:

public class SuperService {@Audited public String deliverService (String uid) {return uid; }}

Vytvorili sme túto jednoduchú službu a anotovali sme metódu, ktorú sme chceli zachytiť pomocou @Auditované anotácia.

Ak chcete povoliť zachytávač CDI, je potrebné zadať úplný názov triedy v priečinku beans.xml súbor, ktorý sa nachádza v priečinku META-INF adresár:

  com.baeldung.interceptor.AuditedInterceptor 

Overiť, že zachytávač skutočne fungoval poďme teraz vykonať nasledujúci test:

verejná trieda TestInterceptor {zvarový zvar; Kontajner WeldContainer; @ Pred public void init () {weld = new Weld (); kontajner = weld.initialize (); } @After public void shutdown () {weld.shutdown (); } @Test public void givenTheService_whenMethodAndInterceptorExecuted_thenOK () {SuperService superService = container.select (SuperService.class) .get (); Kód reťazca = "123456"; superService.deliverService (kód); Assert.assertTrue (AuditedInterceptor.calledBefore); Assert.assertTrue (AuditedInterceptor.calledAfter); }}

V tomto rýchlom teste najskôr získame fazuľu SuperSlužba z kontajnera, potom vyvolajte obchodnú metódu deliverService na ňom a skontrolujte ten zachytávač Auditovaný interceptor bol v skutočnosti vyvolaný overením jeho stavových premenných.

Tiež máme @ Predtým a @ Potom anotované metódy, pri ktorých inicializujeme a vypíname zvarový kontajner.

5. Úvahy o CDI

Môžeme poukázať na nasledujúce výhody interceptorov CDI:

  • Je to štandardná vlastnosť špecifikácie Jakarta EE
  • Niektoré knižnice implementácie CDI možno použiť v prostredí Java SE
  • Môže sa použiť, keď má náš projekt prísne obmedzenia týkajúce sa knižníc tretích strán

Nevýhody interceptorov CDI sú nasledujúce:

  • Tesné spojenie medzi triedou s obchodnou logikou a zachytávačom
  • Je ťažké zistiť, ktoré triedy sú v projekte zachytené
  • Nedostatok flexibilného mechanizmu na použitie zachytávačov na skupinu metód

6. Jarný aspektJ

Spring podporuje podobnú implementáciu funkčnosti zachytávača aj pomocou syntaxe AspectJ.

Najprv musíme do POM pridať nasledujúce závislosti Spring a AspectJ:

 org.springframework jarný kontext 5.2.8.RELEASE org.aspectj aspektjweaver 1.9.2 

Najnovšie verzie jarného kontextu, aspectjweaver sa nachádzajú v úložisku Maven.

Teraz môžeme vytvoriť jednoduchý aspekt pomocou syntaxe anotácie AspectJ:

@Aspect verejná trieda SpringTestAspect {@Autowired private List akumulátor; @Around ("execution (* com.baeldung.spring.service.SpringSuperService. * (..))") public Object auditMethod (ProceedingJoinPoint jp) hodí Throwable {String methodName = jp.getSignature (). GetName (); akumulator.add ("Volanie na" + nazov metody); Objekt obj = jp.proceed (); akumulator.add ("Metóda úspešne volaná:" + methodName); návrat obj; }}

Vytvorili sme aspekt, ktorý sa vzťahuje na všetky metódy SpringSuperService trieda - ktorá pre zjednodušenie vyzerá takto:

verejná trieda SpringSuperService {verejný reťazec getInfoFromService (reťazcový kód) {návratový kód; }}

7. Spring AspectJ Aspect Apply

Aby sme overili, či sa tento aspekt na službu skutočne vzťahuje, napíšeme nasledujúci test jednotky:

@RunWith (SpringRunner.class) @ContextConfiguration (classes = {AppConfig.class}) verejná trieda TestSpringInterceptor {@Autowired SpringSuperService springSuperService; @Autowired súkromný akumulátor zoznamu; @Test public void givenService_whenServiceAndAspectExecuted_thenOk () {String code = "123456"; Výsledok reťazca = springSuperService.getInfoFromService (kód); Assert.assertThat (akumulator.size (), je (2)); Assert.assertThat (akumulator.get (0), je ("Volať na getInfoFromService")); Assert.assertThat (akumulator.get (1), je ("Metóda bola úspešne volaná: getInfoFromService")); }}

V tomto teste vstrekneme našu službu, zavoláme metódu a skontrolujeme výsledok.

Konfigurácia vyzerá takto:

@Configuration @EnableAspectJAutoProxy verejná trieda AppConfig {@Bean verejná SpringSuperService springSuperService () {vrátiť nový SpringSuperService (); } @Bean public SpringTestAspect springTestAspect () {return new SpringTestAspect (); } @Bean public List getAccumulator () {return new ArrayList (); }}

Jedným z dôležitých aspektov tu v @EnableAspectJAutoProxy anotácia - ktorá umožňuje podporu pre prácu s komponentmi označenými AspectJ @Aspect anotácia, podobná funkčnosti, ktorá sa nachádza v prvku XML Spring.

8. Aspekty jari

Poďme poukázať na niekoľko výhod používania Spring AspectJ:

  • Interceptory sú oddelené od obchodnej logiky
  • Interceptory môžu mať prospech z injekcie závislosti
  • Interceptor má všetky informácie o konfigurácii sám o sebe
  • Pridanie nových zachytávačov by nevyžadovalo rozšírenie existujúceho kódu
  • Interceptor má flexibilný mechanizmus na výber metód, ktoré majú byť zachytené
  • Použiteľné bez Jakarta EE

A samozrejme niekoľko nevýhod:

  • Aby ste mohli vyvíjať zachytávače, musíte poznať syntax AspectJ
  • Krivka učenia pre zachytávače AspectJ je vyššia ako pre zachytávače CDI

9. Interceptor CDI vs Spring AspectJ

Ak váš súčasný projekt používa jar, potom je dobrá voľba zvážiť Spring AspectJ.

Ak používate plnohodnotný aplikačný server alebo váš projekt nepoužíva Spring (alebo iné rámce, napr. Google Guice) a je to striktne Jakarta EE, nezostáva nič iné, ako zvoliť zachytávač CDI.

10. Záver

V tomto článku sme sa zaoberali dvoma implementáciami modelu interceptorov: CDI interceptor a Spring AspectJ. Pokryli sme výhody a nevýhody každej z nich.

Zdrojový kód pre príklady tohto článku nájdete v našom úložisku na GitHub.


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