CDI interceptor vs tavaszi szempontJ

1. Bemutatkozás

Az Interceptor mintát általában új, átfogó funkcionalitás vagy logika hozzáadásához használják egy alkalmazásban, és számos könyvtárban szilárd támogatást nyújt.

Ebben a cikkben e nagy könyvtárak közül kettőt tárgyalunk: a CDI elfogókat és a Spring AspectJ-t.

2. CDI elfogó projekt beállítása

A CDI hivatalosan támogatott a Jakarta EE számára, de néhány megvalósítás támogatja a CDI Java SE környezetben történő használatát. A Weld a CDI megvalósításának egyik példája, amelyet a Java SE támogat.

A CDI használatához be kell importálnunk a Weld könyvtárat a POM-ba:

 org.jboss.weld.se varrat-se-core 3.0.5.Végső 

A legújabb Weld könyvtár a Maven tárházban található.

Hozzunk létre most egy egyszerű elfogót.

3. A CDI Interceptor bemutatása

Az elfogáshoz szükséges osztályok kijelöléséhez hozzuk létre az elfogó kötését:

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

Miután meghatároztuk az elfogó kötését, meg kell határoznunk az elfogó tényleges megvalósítását:

@Audited @Interceptor public class AuditedInterceptor {public static boolean calledBefore = false; public static boolean nevűAfter = false; @AroundInvoke public Object auditMethod (InvocationContext ctx) dobja a Kivételt {calledBefore = true; Objektum eredménye = ctx.proceed (); calledAfter = igaz; visszatérési eredmény; }}

Minden @AroundInvoke módszer a javax.interceptor.InvocationContext argumentumot ad vissza java.lang.Tárgy, és dobhat egy Kivétel.

És így, amikor egy módszert feljegyezünk az újval @Könyvvizsgálat felület, auditMethod lesz előbb meghívva, és csak ezután folytatódik a cél módszer is.

4. Alkalmazza a CDI Interceptort

Alkalmazzuk a létrehozott elfogót valamilyen üzleti logikára:

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

Létrehoztuk ezt az egyszerű szolgáltatást, és megjegyeztük azt a módszert, amelyet meg akartunk fogni a @ Auditált annotáció.

A CDI elfogó engedélyezéséhez meg kell adni a teljes osztály nevét a bab.xml fájl, amely a META-INF Könyvtár:

  com.baeldung.interceptor.AuditedInterceptor 

Az elfogó ellenőrzése valóban működött futtassuk most a következő tesztet:

nyilvános osztály TestInterceptor {Hegesztési varrat; WeldContainer konténer; @A nyilvános void előtt init () {hits = new Weld (); tartály = hegesztés.inicialize (); } @A nyilvános üresség leállítása után () {hits.shutdown (); } @Test public void givenTheService_whenMethodAndInterceptorExecuted_thenOK () {SuperService superService = container.select (SuperService.class) .get (); Karakterlánc kód = "123456"; superService.deliverService (kód); Assert.assertTrue (AuditedInterceptor.calledBefore); Assert.assertTrue (AuditedInterceptor.calledAfter); }}

Ebben a gyors tesztben először megkapjuk a babot SuperService a tárolóból, majd hívja meg az üzleti módszert deliveryService rajta és ellenőrizze azt az elfogót AuditedInterceptor valójában állapotváltozóinak érvényesítésével hívták meg.

Nekünk is van @Előtt és @Utána kommentált módszerek, amelyekben inicializáljuk és leállítjuk a Weld tárolót.

5. CDI szempontok

Kiemelhetjük a CDI elfogók következő előnyeit:

  • Ez a Jakarta EE specifikáció standard jellemzője
  • Néhány CDI implementációs könyvtár használható a Java SE-ben
  • Akkor használható, ha projektünknek szigorú korlátai vannak a külső könyvtárakra nézve

A CDI elfogók hátrányai a következők:

  • Szoros összekapcsolás az osztály és az üzleti logika és az elfogó között
  • Nehéz meglátni, hogy mely osztályokat hallgatják le a projektben
  • Rugalmas mechanizmus hiánya az elfogók metóduscsoportra történő alkalmazásához

6. Tavaszi szempontJ

A Spring az elfogó funkciók hasonló megvalósítását támogatja az AspectJ szintaxist is felhasználva.

Először hozzá kell adnunk a következő Spring és AspectJ függőségeket a POM-hoz:

 org.springframework tavaszi kontextus 5.2.8. RELEASE org.aspectj szempontjweaver 1.9.2 

A Spring context legújabb verziója, a aspektjweaver, megtalálható a Maven tárházban.

Most létrehozhatunk egy egyszerű szempontot az AspectJ annotációs szintaxisa segítségével:

@Aspect public class SpringTestAspect {@Autowired private list accumulator; @Around ("végrehajtás (* com.baeldung.spring.service.SpringSuperService. * (..))") public Object auditMethod (ProceedingJoinPoint jp) dobja Throwable {String methodName = jp.getSignature (). GetName (); accumulator.add ("Hívás" + metódusnév); Object obj = jp.proceed (); accumulator.add ("A módszer sikeresen meghívva:" + methodName); return obj; }}

Létrehoztunk egy aspektust, amely az összes módszerre vonatkozik SpringSuperService osztály - amely az egyszerűség kedvéért így néz ki:

public class SpringSuperService {public String getInfoFromService (String code) {return code; }}

7. Tavaszi szempontJ Aspect Apply

Annak igazolása érdekében, hogy ez a szempont valóban vonatkozik a szolgáltatásra, írjuk meg a következő egységtesztet:

@RunWith (SpringRunner.class) @ContextConfiguration (class = {AppConfig.class}) public class TestSpringInterceptor {@Autowired SpringSuperService springSuperService; @Autowired private List accumulator; @Test public void givenService_whenServiceAndAspectExecuted_thenOk () {String code = "123456"; Karakterlánc eredménye = springSuperService.getInfoFromService (kód); Assert.assertThat (accumulator.size (), is (2)); Assert.assertThat (accumulator.get (0), is ("Hívás a getInfoFromService szolgáltatáshoz")); Assert.assertThat (accumulator.get (1), is ("A módszer sikeresen meghívva: getInfoFromService")); }}

Ebben a tesztben beadjuk a szolgáltatásunkat, meghívjuk a módszert és ellenőrizzük az eredményt.

A konfiguráció így néz ki:

@Configuration @EnableAspectJAutoProxy public class AppConfig {@Bean public SpringSuperService springSuperService () {return new SpringSuperService (); } @Bean public SpringTestAspect springTestAspect () {return new SpringTestAspect (); } @Bean nyilvános lista getAccumulator () {return new ArrayList (); }}

Az egyik fontos szempont itt a @EnableAspectJAutoProxy annotáció - amely lehetővé teszi az AspectJ-vel jelölt alkatrészek kezelését @Vonatkozás kommentár, hasonlóan a Spring XML elemében található funkcionalitáshoz.

8. Tavaszi szempontJ szempontok

Rámutatunk a Spring AspectJ használatának néhány előnyére:

  • Az elfogókat leválasztják az üzleti logikáról
  • Az elfogók részesülhetnek a függőségi injekcióból
  • Az interceptor magában foglalja az összes konfigurációs információt
  • Új elfogók hozzáadásához nem szükséges a meglévő kód bővítése
  • Az elfogónak rugalmas mechanizmusa van arra, hogy kiválassza az elfogandó módszereket
  • Jakarta EE nélkül is használható

És természetesen néhány hátrány:

  • Az elfogók fejlesztéséhez ismernie kell az AspectJ szintaxist
  • Az AspectJ interceptorok tanulási görbéje magasabb, mint a CDI interceptoroké

9. CDI interceptor vs tavaszi szempontJ

Ha a jelenlegi projekt a tavaszt használja, akkor a Spring AspectJ megfontolása jó választás.

Ha teljes körű alkalmazásszervert használ, vagy a projektje nem használja a Spring-et (vagy más keretrendszert, például a Google Guice-ot), és szigorúan Jakarta EE, akkor nem marad más hátra, mint a CDI elfogót választani.

10. Következtetés

Ebben a cikkben az elfogó minta két megvalósításával foglalkoztunk: a CDI elfogóval és a Spring AspectJ-vel. Mindegyiknek megvizsgáltuk az előnyeit és hátrányait.

A cikk példáinak forráskódja megtalálható a GitHub tárolójában.