Bevezetés az eseményértesítési modellbe a CDI 2.0-ban

1. Áttekintés

A CDI (Contexts and Dependency Injection) a Jakarta EE platform szokásos függőségi injekciós keretrendszere.

Ebben az oktatóanyagban megvizsgáljuk a CDI 2.0-t, és hogyan épít a CDI 1.x hatékony, típusbiztos befecskendezési mechanizmusára. továbbfejlesztett, teljes funkcionalitású eseményértesítési modell hozzáadása.

2. A Maven-függőségek

A kezdéshez elkészítünk egy egyszerű Maven-projektet.

Szükségünk van egy CDI 2.0-kompatibilis tárolóra, és a CDI referencia implementációja, a Weld jól illeszkedik:

  javax.enterprise cdi-api 2.0.SP1 org.jboss.weld.se hegesztett se-core 3.0.5.Végső 

Szokás szerint a legújabb verziókat is kihúzhatjuk cdi-api és hegesztett-se-mag a Maven Central-tól.

3. Az egyedi események megfigyelése és kezelése

Egyszerűen fogalmazva, a CDI 2.0 eseményértesítési modell a Megfigyelő minta klasszikus megvalósítása, alapján @ Megfigyeli módszer-paraméter annotáció. Így lehetővé teszi számunkra a megfigyelői módszerek egyszerű meghatározását, amelyek automatikusan meghívhatók egy vagy több eseményre válaszul.

Például meghatározhatunk egy vagy több babot, amelyek egy vagy több konkrét eseményt váltanak ki, míg más babot értesítenek az eseményekről, és ennek megfelelően reagálnak.

Annak tisztázása érdekében, hogy ez hogyan működik, elkészítünk egy egyszerű példát, ideértve az alapvető szolgáltatási osztályt, az egyedi eseményosztályt és a megfigyelő módszert, amely reagál az egyedi eseményeinkre.

3.1. Alapszintű szolgáltatási osztály

Kezdjük egy egyszerű létrehozásával TextService osztály:

public class TextService {public String parseText (String text) {return text.toUpperCase (); }} 

3.2. Egyéni eseményosztály

Ezután határozzunk meg egy minta eseményosztályt, amely a-t veszi fel Húr argumentum a konstruktorában:

public class ExampleEvent {private final String eventMessage; public ExampleEvent (String eventMessage) {this.eventMessage = eventMessage; } // getter}

3.3. Megfigyelő módszer meghatározása a @ Megfigyeli Megjegyzés

Most, hogy meghatároztuk szolgáltatási és eseményosztályainkat, használjuk a @ Megfigyeli annotáció, hogy megfigyelő módszert hozzunk létre a mi PéldaEvent osztály:

public class ExampleEventObserver {public String onEvent (@Observes ExampleEvent event, TextService textService) {return textService.parseText (event.getEventMessage ()); }}

Míg első látásra a onEvent () metódus meglehetősen triviálisnak tűnik, valójában sok funkcionalitást foglal magában a @ Megfigyeli annotáció.

Mint láthatjuk, a onEvent () módszer egy eseménykezelő, amely megteszi PéldaEvent és TextService objektumok mint érvek.

Tartsuk szem előtt, hogy a @ Megfigyeli az annotáció a szokásos injekciós pont. Ennek eredményeként a CDI teljesen inicializált példányokat hoz létre számunkra, és beinjekciózza őket a megfigyelő módszerbe.

3.4. A CDI 2.0 konténer inicializálása

Ezen a ponton hoztuk létre szolgáltatásaink és eseményeink osztályait, és meghatároztunk egy egyszerű megfigyelő módszert az eseményeinkre való reagálásra. De hogyan utasíthatjuk a CDI-t arra, hogy futtassa ezeket az eseteket futás közben?

Itt mutatja be az eseményértesítési modell a lehető legteljesebb mértékben a funkcionalitását. Egyszerűen inicializáljuk az újat SeContainer végrehajtása és egy vagy több esemény kirúgása a fireEvent () módszer:

SeContainerInitializer containerInitializer = SeContainerInitializer.newInstance (); try (SeContainer container = containerInitializer.initialize ()) {container.getBeanManager (). fireEvent (új ExampleEvent ("Üdvözöljük a Baeldungban!")); }

Ne feledje, hogy a SeContainerInitializer és SeContainer objektumok, mert a CDI-t Java SE környezetben használjuk, nem pedig Jakarta EE-ben.

Az összes mellékelt megfigyelői módszerről értesítést kap, amikor a PéldaEvent magát az esemény terjesztésével rúgják ki.

Mivel az összes objektum argumentumként került átadásra a @ Megfigyeli az annotáció teljesen inicializálódik, a CDI gondoskodik az egész bekötéséről TextService objektumgrafikon számunkra, mielőtt befecskendeznénk a onEvent () módszer.

Dióhéjban, megvannak a típusbiztonságos IoC tároló előnyei, valamint a funkciókban gazdag eseményértesítési modell.

4. A ContainerInialized Esemény

Az előző példában egyedi eseményt használtunk arra, hogy egy eseményt átadjunk egy megfigyelő metódusnak, és teljesen inicializáljuk TextService tárgy.

Természetesen ez akkor hasznos, ha valóban egy vagy több eseményt kell terjesztenünk alkalmazásunk több pontján.

Néha egyszerűen egy csomó teljesen inicializált objektumot kell beszereznünk, amelyek felhasználásra készek az alkalmazásosztályainkon belül, anélkül, hogy további események megvalósításán kellene átesnie.

Eddig a végéig, A CDI 2.0 biztosítja a ContainerInialized eseményosztály, amely automatikusan elindul a Weld tároló inicializálásakor.

Vessünk egy pillantást arra, hogyan használhatjuk a ContainerInialized esemény az irányítás átadására a PéldaEventObserver osztály:

public class ExampleEventObserver {public String onEvent (@Observes ContainerInitialized event, TextService textService) {return textService.parseText (event.getEventMessage ()); }} 

És ezt ne feledje a ContainerInialized esemény osztály Weld-specifikus. Tehát át kell alakítanunk a megfigyelő módszereinket, ha más CDI megvalósítást alkalmazunk.

5. Feltételes megfigyelő módszerek

Jelenlegi megvalósításában a PéldaEventObserver osztály alapértelmezés szerint egy feltétel nélküli megfigyelő módszert határoz meg. Ez azt jelenti a megfigyelő módszert mindig értesíteni kell a mellékelt eseményről, függetlenül attól, hogy létezik-e az osztály egy példánya a jelenlegi kontextusban.

Hasonlóképpen mi is határozzon meg egy feltételes megfigyelő módszert megadásával noticeObserver = IF_EXISTS érvként a @ Megfigyeli kommentár:

public String onEvent (@Observes (noticeObserver = IF_EXISTS) ExampleEvent esemény, TextService textService) {return textService.parseText (event.getEventMessage ()); } 

Ha feltételes megfigyelő módszert alkalmazunk, a metódus csak akkor kap értesítést az illesztési eseményről, ha a megfigyelő metódust meghatározó osztály egy példánya létezik a jelenlegi kontextusban.

6. Tranzakciós megfigyelő módszerek

Aktiválhatunk egy tranzakción belüli eseményeket is, például egy adatbázis frissítési vagy eltávolítási műveletet. Ehhez definiálhatunk tranzakciós megfigyelő módszereket a alatt érv a @ Megfigyeli annotáció.

A. Minden lehetséges értéke alatt argumentum egy tranzakció egy adott szakaszának felel meg:

  • BEFORE_COMPLETION
  • AFTER_COMPLETION
  • AFTER_SIKER
  • AFTER_FAILURE

Ha kirúgjuk a PéldaEvent esemény egy tranzakción belül, át kell alakítanunk a onEvent () módszer ennek megfelelően kezelni az eseményt a szükséges szakaszban:

public String onEvent (@Observes (aikana = AFTER_COMPLETION) ExampleEvent esemény, TextService textService) {return textService.parseText (event.getEventMessage ()); }

Tranzakciós megfigyelő módszerről csak az adott tranzakció illesztési szakaszában értesítjük a teljesített eseményt.

7. Megfigyelő módszerek rendezése

A CDI 2.0 eseményértesítési modelljében szereplő másik szép fejlesztés az a lehetőség, hogy rendelést vagy prioritást állítson be az adott esemény megfigyelőinek hívására.

Könnyen meghatározhatjuk a megfigyelői módszerek meghívásának sorrendjét a @Kiemelten fontos annotáció után @ Megfigyeli.

Annak megértéséhez, hogy ez a funkció hogyan működik, határozzunk meg egy másik megfigyelő módszert, azon kívül, amelyik PéldaEventObserver megvalósítja:

public class AnotherExampleEventObserver {public String onEvent (@Observes ExampleEvent event) {return event.getEventMessage (); }}

Ebben az esetben alapértelmezés szerint mindkét megfigyelő módszer prioritása lesz. Így egyszerűen kiszámíthatatlan, hogy a CDI milyen sorrendben fogja őket használni.

Könnyen megoldhatjuk ezt úgy, hogy minden metódushoz hozzárendelünk egy invokációs prioritást a @Kiemelten fontos kommentár:

public String onEvent (@Observes @Priority (1) ExampleEvent esemény, TextService textService) {// ... implementáció} 
public String onEvent (@Observes @Priority (2) ExampleEvent esemény) {// ... implementáció}

Az elsőbbségi szintek természetes sorrendet követnek. Ezért a CDI először a megfigyelő módszert hívja meg, amelynek prioritási szintje: 1 és másodsorban a metódust hívja meg, amelynek prioritási szintje: 2.

Hasonlóképpen, ha ugyanazt a prioritási szintet alkalmazzuk két vagy több módszerrel, a sorrend ismét meghatározatlan.

8. Aszinkron események

Az eddigi összes példában szinkronban indítottuk az eseményeket. A CDI 2.0 azonban lehetővé teszi számunkra az aszinkron események egyszerű elindítását is. Aszinkron megfigyelő módszerek akkor ezeket az aszinkron eseményeket különböző szálakban kezelje.

Egy eseményt aszinkron módon lőhetünk a fireAsync () módszer:

public class ExampleEventSource {@Inject Event exampleEvent; public void fireEvent () {exampleEvent.fireAsync (új ExampleEvent ("Üdvözöljük a Baeldungban!")); }}

A babok olyan eseményeket tűznek ki, amelyek a Esemény felület. Ezért injekciózhatjuk őket, mint bármely más hagyományos babot.

Az aszinkron esemény kezeléséhez meg kell határoznunk egy vagy több aszinkron megfigyelő módszert a @ObservesAsync kommentár:

public class AsynchronousExampleEventObserver {public void onEvent (@ObservesAsync ExampleEvent event) {// ... implementáció}}

9. Következtetés

Ebben a cikkben, megtanultuk a CDI 2.0-hoz mellékelt továbbfejlesztett eseményértesítési modell használatának megkezdését.

Szokás szerint az ebben az oktatóanyagban bemutatott összes kódminta elérhető a GitHubon.