Uvod u model obavijesti o događajima u CDI 2.0

1. Pregled

CDI (Contexts and Dependency Injection) je standardni okvir za ubrizgavanje ovisnosti platforme Jakarta EE.

U ovom uputstvu ćemo pogledati CDI 2.0 i kako se temelji na moćnom, tipu sigurnom mehanizmu ubrizgavanja CDI 1.x dodavanje poboljšanog, potpuno opremljenog modela obavijesti o događajima.

2. Ovisnosti Mavena

Za početak ćemo izraditi jednostavan Maven projekt.

Treba nam spremnik kompatibilan sa CDI 2.0, a Weld, referentna implementacija CDI-a, dobro se uklapa:

  javax.enterprise cdi-api 2.0.SP1 org.jboss.weld.se zavar-se-core 3.0.5.Final 

Kao i obično, možemo izvući najnovije verzije cdi-api i jezgra za zavarivanje iz Maven Central.

3. Promatranje i rukovanje prilagođenim događajima

Jednostavno rečeno, model obavijesti o događajima CDI 2.0 klasična je provedba uzorka Promatrača, bazirano na @Opaža bilješka metoda-parametar. Stoga nam omogućuje lako definiranje metoda promatrača, koje se mogu automatski pozvati kao odgovor na jedan ili više događaja.

Na primjer, mogli bismo definirati jedan ili više graha, koji bi pokrenuli jedan ili više specifičnih događaja, dok bi drugi grah bio obaviješten o događajima i reagirao bi u skladu s tim.

Da bismo jasnije pokazali kako ovo funkcionira, sagradit ćemo jednostavan primjer, uključujući osnovnu uslužnu klasu, prilagođenu klasu događaja i metodu promatrača koja reagira na naše prilagođene događaje.

3.1. Osnovna klasa usluge

Počnimo s izradom jednostavnog TextService razred:

javna klasa TextService {javni niz parseText (tekst niza) {return text.toUpperCase (); }} 

3.2. Prilagođena klasa događaja

Dalje, definirajmo primjer klase događaja koja traje Niz argument u svom konstruktoru:

javna klasa ExampleEvent {private final String eventMessage; javni ExampleEvent (String eventMessage) {this.eventMessage = eventMessage; } // dobivač}

3.3. Definiranje promatračke metode pomoću @Opaža Bilješka

Sad kad smo definirali klase usluga i događaja, poslužimo se @Opaža napomena za stvaranje metode promatrača za našu ExampleEvent razred:

javna klasa ExampleEventObserver {javni niz onEvent (@Observations ExampleEvent event, TextService textService) {return textService.parseText (event.getEventMessage ()); }}

Iako je na prvi pogled provedba onEvent () metoda izgleda prilično trivijalno, zapravo obuhvaća puno funkcionalnosti kroz @Opaža bilješka.

Kao što vidimo, onEvent () metoda je obrađivač događaja koji traje ExampleEvent i TextService objekti kao argumenti.

Imajmo na umu da su svi argumenti navedeni nakon @Opaža napomene su standardne točke ubrizgavanja. Kao rezultat toga, CDI će za nas stvoriti potpuno inicijalizirane instance i ubrizgati ih u metodu promatrača.

3.4. Inicijalizacija našeg CDI 2.0 spremnika

U ovom smo trenutku stvorili klase usluga i događaja i definirali smo jednostavnu metodu promatrača da reagira na naše događaje. Ali kako uputiti CDI da ubrizga ove instance tijekom izvođenja?

Evo gdje model obavijesti o događajima u potpunosti pokazuje svoju funkcionalnost. Jednostavno inicijaliziramo novo SeContainer implementacija i aktiviranje jednog ili više događaja putem fireEvent () metoda:

SeContainerInitializer containerInitializer = SeContainerInitializer.newInstance (); try (SeContainer container = containerInitializer.initialize ()) {container.getBeanManager (). fireEvent (novi ExampleEvent ("Dobrodošli u Baeldung!")); }

Imajte na umu da koristimo SeContainerInitializer i SeContainer objekata jer CDI koristimo u Java SE okruženju, a ne u Jakarti EE.

Sve priložene metode promatrača bit će obaviještene kada ExampleEvent otpušta se širenjem samog događaja.

Budući da su svi objekti proslijeđeni kao argumenti nakon @Opaža napomena će biti u potpunosti inicijalizirana, CDI će se pobrinuti za ožičenje cjeline TextService objektni graf za nas, prije nego što ga ubrizgamo u onEvent () metoda.

U suštini, imamo prednosti IoC spremnika koji je siguran za tip, zajedno s modelom obavijesti o događajima bogatim značajkama.

4. The ContainerInitialized Događaj

U prethodnom smo primjeru koristili prilagođeni događaj da bismo događaj proslijedili metodi promatrača i dobili potpuno inicijaliziranu TextService objekt.

Naravno, ovo je korisno kada stvarno moramo proširiti jedan ili više događaja na više točaka naše aplikacije.

Ponekad jednostavno trebamo dobiti hrpu potpuno inicijaliziranih objekata koji su spremni za upotrebu u našim aplikacijskim klasama, bez prolaska kroz provedbu dodatnih događaja.

Do kraja, CDI 2.0 nudi ContainerInitialized klasa događaja, koja se automatski aktivira kad se spremnik za zavarivanje pokrene.

Pogledajmo kako možemo koristiti ContainerInitialized događaj za prijenos kontrole na ExampleEventObserver razred:

javna klasa ExampleEventObserver {javni niz onEvent (@Observations ContainerInitialized događaj, TextService textService) {return textService.parseText (event.getEventMessage ()); }} 

I imajte to na umu the ContainerInitialized klasa događaja je specifična za zavarivanje. Dakle, morat ćemo refaktorirati naše metode promatrača ako koristimo drugačiju CDI implementaciju.

5. Metode uvjetnog promatrača

U svojoj trenutnoj provedbi, naš ExampleEventObserver klasa prema zadanim postavkama definira bezuvjetnu metodu promatrača. Ovo znači to metoda promatrača uvijek će biti obaviještena o navedenom događaju, bez obzira na to postoji li klasa u trenutnom kontekstu ili ne.

Isto tako, možemo definirati metodu uvjetnog promatrača navođenjem notifyObserver = AKO POSTOJI kao argument za @Opaža napomena:

javni String onEvent (@Observa (notifyObserver = IF_EXISTS) ExampleEvent event, TextService textService) {return textService.parseText (event.getEventMessage ()); } 

Kada koristimo metodu uvjetnog promatrača, metoda će biti obaviještena o događaju podudaranja samo ako u trenutnom kontekstu postoji instanca klase koja definira metodu promatrača.

6. Transakcijske metode promatrača

Također možemo aktivirati događaje unutar transakcije, poput ažuriranja baze podataka ili uklanjanja. Da bismo to učinili, možemo definirati metode promatrača transakcija dodavanjem znaka tijekom argument za @Opaža bilješka.

Svaka moguća vrijednost tijekom argument odgovara određenoj fazi transakcije:

  • PRIJE_ZAPUNJENJA
  • NAKON_IZVRŠENJA
  • NAKON USPJEHA
  • NAKON POSTOJANJA

Ako ispalimo ExampleEvent događaj unutar transakcije, moramo refaktorizirati onEvent () metoda prema kojoj se obrađuje događaj tijekom potrebne faze:

javni String onEvent (@Observa (tijekom = AFTER_COMPLETION) ExampleEvent event, TextService textService) {return textService.parseText (event.getEventMessage ()); }

Metoda transakcijskog promatrača bit će obaviještena o isporučenom događaju samo u fazi podudaranja dane transakcije.

7. Naručivanje metoda promatrača

Još jedno lijepo poboljšanje uključeno u model obavijesti o događaju CDI 2.0 je sposobnost postavljanja redoslijeda ili prioriteta za pozivanje promatrača određenog događaja.

Redoslijedom pozivanja metoda promatrača možemo lako definirati određivanjem @Prioritet napomena nakon @Opaža.

Da bismo razumjeli kako ova značajka funkcionira, definirajmo još jednu metodu promatrača, osim one koja ExampleEventObserver provodi:

javna klasa AnotherExampleEventObserver {javni niz onEvent (@Observations ExampleEvent event) {return event.getEventMessage (); }}

U ovom će slučaju obje metode promatrača prema zadanim postavkama imati isti prioritet. Stoga je redoslijed kojim će se CDI pozivati ​​na njih jednostavno nepredvidljiv.

To možemo lako popraviti dodjeljujući svakoj metodi prioritet pozivanja putem @Prioritet napomena:

javni String onEvent (@Observa @Priority (1) ExampleEvent event, TextService textService) {// ... implementacija} 
javni String onEvent (@Observa @Priority (2) ExampleEvent event) {// ... implementacija}

Prioritetne razine slijede prirodni poredak. Stoga će CDI prvo pozvati metodu promatrača s razinom prioriteta 1 i pozvat će drugu metodu s prioritetnom razinom 2.

Također, ako koristimo istu razinu prioriteta u dvije ili više metoda, redoslijed je opet nedefiniran.

8. Asinkroni događaji

U svim primjerima koje smo do sada naučili, događaje smo aktivirali sinkrono. Međutim, CDI 2.0 omogućuje nam da lako aktiviramo i asinkrone događaje. Asinhrone metode promatrača tada mogu obrađuju ove asinkrone događaje u različitim nitima.

Događaj možemo aktivirati asinkrono s fireAsync () metoda:

javna klasa ExampleEventSource {@Inject Event exampleEvent; public void fireEvent () {exampleEvent.fireAsync (novi ExampleEvent ("Dobro došli u Baeldung!")); }}

Grah pokreće događaje koji su implementacije Događaj sučelje. Stoga ih možemo ubrizgati kao bilo koji drugi konvencionalni grah.

Da bismo obradili naš asinkroni događaj, moramo definirati jednu ili više metoda asinkronog promatrača s @ObservationsAsync napomena:

javna klasa AsynchronousExampleEventObserver {javna void onEvent (@ObservesAsync ExampleEvent event) {// ... implementacija}}

9. Zaključak

U ovom članku, naučili smo kako započeti korištenje poboljšanog modela obavijesti o događajima u paketu s CDI 2.0.

Kao i obično, svi uzorci koda prikazani u ovom vodiču dostupni su na GitHubu.


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