CDI presretač vs Spring AspectJ

1. Uvod

Uzorak presretača obično se koristi za dodavanje nove, presječne funkcionalnosti ili logike u aplikaciji, a ima solidnu podršku u velikom broju knjižnica.

U ovom ćemo članku pokriti i usporediti dvije glavne knjižnice: presretače CDI i Spring AspectJ.

2. Postavljanje CDI Interceptor projekta

CDI je službeno podržan za Jakarta EE, ali neke implementacije pružaju podršku korištenju CDI-a u Java SE okruženju. Zavar se može smatrati jednim primjerom implementacije CDI-a koji je podržan u Java SE.

Da bismo koristili CDI, moramo uvesti biblioteku Weld u naš POM:

 org.jboss.weld.se zavarivanje-jezgra 3.0.5.Finalno 

Najnovija biblioteka Weld nalazi se u spremištu Maven.

Stvorimo sada jednostavan presretač.

3. Predstavljamo CDI presretač

Da bismo odredili klase koje smo trebali presresti, stvorimo vezu presretača:

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

Nakon što definiramo vezanje presretača, moramo definirati stvarnu implementaciju presretača:

@Audited @Interceptor javna klasa AuditedInterceptor {javna statička logička vrijednost calledBefore = false; javna statička logička vrijednost pozvanaAfter = false; @AroundInvoke public Object auditMethod (InvocationContext ctx) baca izuzetak {pozvanoBefore = true; Rezultat objekta = ctx.proceed (); pozvanoAfter = true; povratni rezultat; }}

Svaki @AroundInvoke metoda traje a javax.interceptor.InvocationContext argument, vraća a java.lang.Object, i može baciti znak Iznimka.

I tako, kad metodu označimo novim @Revizija sučelje, auditMethod prvo će se pozvati, a tek onda se nastavlja i ciljna metoda.

4. Primijenite CDI presretač

Primijenimo stvoreni presretač na neku poslovnu logiku:

javna klasa SuperService {@Audited public String DeliveryService (String uid) {return uid; }}

Stvorili smo ovu jednostavnu uslugu i označili metodu koju smo htjeli presresti s @ Revidirano bilješka.

Da biste omogućili presretač CDI, potrebno je navesti puno ime klase u grah.xml datoteka koja se nalazi u META-INF imenik:

  com.baeldung.interceptor.AuditedInterceptor 

Da bi se potvrdilo da je presretač zaista radio pokrenimo sada sljedeći test:

javna klasa TestInterceptor {zavar; Spremnik za zavarivanje; @Prije javne void init () {zavar = novi zavar (); spremnik = zavar.inicialize (); } @Nakon isključenja javne praznine () {weld.shutdown (); } @Test javna praznina givenTheService_whenMethodAndInterceptorExecuted_thenOK () {SuperService superService = container.select (SuperService.class) .get (); Oznaka niza = "123456"; superService.deliverService (kod); Assert.assertTrue (AuditedInterceptor.calledBefore); Assert.assertTrue (AuditedInterceptor.calledAfter); }}

U ovom brzom testu prvo dobivamo grah SuperService iz spremnika, a zatim pozovite poslovnu metodu dostavitiService na njemu i provjerite taj presretač AuditedInterceptor zapravo je pozvan provjerom valjanosti njegovih varijabli stanja.

Također imamo @Prije i @Nakon anotirane metode u kojima inicijaliziramo odnosno isključujemo spremnik za zavarivanje.

5. Razmatranja CDI-ja

Možemo istaknuti sljedeće prednosti CDI presretača:

  • To je standardna značajka Jakarta EE specifikacije
  • Neke biblioteke CDI implementacija mogu se koristiti u Java SE
  • Može se koristiti kada naš projekt ima ozbiljna ograničenja na biblioteke trećih strana

Mane CDI presretača su sljedeće:

  • Čvrsta sprega klase s poslovnom logikom i presretačem
  • Teško je vidjeti koje su klase presretnute u projektu
  • Nedostatak fleksibilnog mehanizma za primjenu presretača na skupinu metoda

6. Proljetni aspektJ

Spring podržava sličnu implementaciju presretačke funkcionalnosti koristeći i sintaksu AspectJ.

Prvo u POM moramo dodati sljedeće ovisnosti Spring i AspectJ:

 org.springframework spring-context 5.2.8.Opusti org.aspectj aspektjweaver 1.9.2 

Najnovije verzije proljetnog konteksta, aspektjweaver mogu se naći u spremištu Maven.

Sada možemo stvoriti jednostavan aspekt koristeći sintaksu napomena AspectJ:

@Aspect javni razred SpringTestAspect {@Autowired private List akumulator; @Around ("Execution (* com.baeldung.spring.service.SpringSuperService. * (..))") public Object auditMethod (ProceedingJoinPoint jp) baca Throwable {String methodName = jp.getSignature (). GetName (); akumulator.add ("Poziv na" + imeName); Objekt obj = jp.proceed (); akumulator.add ("Metoda je uspješno pozvana:" + imeName); povratak obj; }}

Stvorili smo aspekt koji se odnosi na sve metode SpringSuperService klasa - koja radi jednostavnosti izgleda ovako:

javna klasa SpringSuperService {javni niz getInfoFromService (kod niza) {povratni kôd; }}

7. Proljetni aspektJ Aspect Apply

Da bismo potvrdili da se taj aspekt stvarno odnosi na uslugu, napišite sljedeći jedinični test:

@RunWith (SpringRunner.class) @ContextConfiguration (classes = {AppConfig.class}) javna klasa TestSpringInterceptor {@Autowired SpringSuperService springSuperService; @Autowired privatni akumulator popisa; @Test javna praznina givenService_whenServiceAndAspectExecuted_thenOk () {String code = "123456"; Rezultat niza = springSuperService.getInfoFromService (kod); Assert.assertThat (akumulator.size (), je (2)); Assert.assertThat (akumulator.get (0), je ("Poziv za dobivanjeInfoFromService")); Assert.assertThat (akumulator.get (1), je ("Metoda je uspješno pozvana: getInfoFromService")); }}

U ovom testu ubrizgavamo našu uslugu, pozivamo metodu i provjeravamo rezultat.

Evo kako izgleda konfiguracija:

@Configuration @EnableAspectJAutoProxy javna klasa AppConfig {@Bean public SpringSuperService springSuperService () {return new SpringSuperService (); } @Bean public SpringTestAspect springTestAspect () {return new SpringTestAspect (); } @Bean javni popis getAccumulator () {return new ArrayList (); }}

Jedan važan aspekt ovdje u @EnableAspectJAutoProxy napomena - koja omogućuje podršku za rukovanje komponentama označenim AspectJ-ima @Aspekt napomena, slična funkciji pronađenoj u Springovom XML elementu.

8. Razmatranja proljetnog aspektaJ

Istaknimo nekoliko prednosti korištenja Spring AspectJ:

  • Presretači su odvojeni od poslovne logike
  • Presretači mogu imati koristi od injekcije ovisnosti
  • Presretač ima sve podatke o konfiguraciji u sebi
  • Dodavanje novih presretača ne bi zahtijevalo povećanje postojećeg koda
  • Presretač ima fleksibilan mehanizam za odabir metoda presretanja
  • Može se koristiti bez Jakarte EE

I naravno nekoliko nedostataka:

  • Morate znati sintaksu AspectJ da biste razvili presretače
  • Krivulja učenja za presretače AspectJ viša je nego za presretače CDI

9. CDI presretač vs Spring AspectJ

Ako vaš trenutni projekt koristi proljeće, onda je razmatranje Spring AspectJ dobar izbor.

Ako koristite potpuno razvijeni poslužitelj aplikacija ili vaš projekt ne koristi Spring (ili druge okvire, npr. Google Guice) i strogo je Jakarta EE, ne preostaje ništa drugo nego odabrati presretač CDI.

10. Zaključak

U ovom smo članku pokrili dvije implementacije uzorka presretača: presretač CDI i Spring AspectJ. Pokrili smo prednosti i nedostatke svakog od njih.

Izvorni kod za primjere ovog članka možete pronaći u našem spremištu na GitHubu.


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