Singleton sesijski grah u Džakarti EE

1. Pregled

Kad god je za određeni slučaj upotrebe potreban jedan primjerak Session Bean-a, možemo koristiti Singleton Session Bean.

U ovom uputstvu to ćemo istražiti na primjeru s aplikacijom Jakarta EE.

2. Maven

Prije svega, moramo definirati potrebne Mavenove ovisnosti u pom.xml.

Definirajmo ovisnosti za EJB API-je i ugrađeni EJB spremnik za implementaciju EJB:

 javax javaee-api 8.0 pod uvjetom org.apache.openejb tomee-ugrađen 1.7.5 

Najnovije verzije možete pronaći na Maven Central na JavaEE API i tomEE.

3. Vrste graha za sjednice

Postoje tri vrste sjemenskog graha. Prije nego što istražimo Singleton Session grah, pogledajmo koja je razlika između životnih ciklusa tri vrste.

3.1. Grah sa zasjedanjem

Bean sesije Stateful održava stanje razgovora s klijentom kojeg komunicira.

Svaki klijent stvara novu instancu Stateful Bean-a i ne dijeli se s drugim klijentima.

Kada komunikacija između klijenta i graha završi, grah sesije također se prekida.

3.2. Grah za sjednice bez državljanstva

Grah sesije bez državljanstva ne održava stanje razgovora s klijentom. Bean sadrži stanje specifično za klijenta samo do trajanja poziva metode.

Uzastopni pozivi metode neovisni su za razliku od graha sesije Stateful.

Spremnik održava skupinu graha bez državljanstva i te primjerke može dijeliti više klijenata.

3.3. Grah pojedinačne sesije

Singleton Session Bean održava stanje graha tijekom cijelog životnog ciklusa aplikacije.

Singleton Session Beans slični su Sessions Beans bez državljanstva, ali samo jedan primjerak Singleton Session Bean kreira se u cijeloj aplikaciji i ne prestaje dok se aplikacija ne isključi.

Pojedinačna inačica graha dijeli se između više klijenata i može mu se istodobno pristupiti.

4. Stvaranje pojedinačnog graha sesije

Počnimo s izradom sučelja za to.

Za ovaj primjer upotrijebimo javax.ejb.Local napomena za definiranje sučelja:

@ Lokalno javno sučelje CountryState {Popis getStates (Niz država); void setStates (država niza, države popisa); }

Koristeći @ Lokalno znači da se grahu pristupa unutar iste aplikacije. Također imamo mogućnost korištenja javax.ejb.Udaljeno napomena koja nam omogućuje daljinski poziv EJB-a.

Sada ćemo definirati klasu građe implementacije EJB. Klasu označavamo kao Singleton Session Bean uporabom anotacije javax.ejb.Singleton.

Uz to, označimo i grah javaxom.ejb.Startup napomena za obavještavanje spremnika EJB da inicijalizira grah pri pokretanju:

@Singleton @Startup javna klasa CountryStateContainerManagedBean implementira CountryState {...}

To se naziva željna inicijalizacija. Ako ne koristimo @Startup, spremnik EJB određuje kada će se inicijalizirati grah.

Također možemo definirati više graha sesije kako bismo inicijalizirali podatke i učitali grah u određenom redoslijedu. Stoga ćemo koristiti, javax.ejb.DependsOn napomena za definiranje ovisnosti našeg graha o ostalim grahima sesije.

Vrijednost za @Ovisi o anotacija je niz imena imena klasa Bean o kojima ovisi naš Bean:

@Singleton @Startup @DependsOn ({"DependentBean1", "DependentBean2"}) javna klasa CountryStateCacheBean implementira CountryState {...}

Mi ćemo definirati inicijalizirati () metoda koja inicijalizira bean i čini ga metodom povratnog poziva životnog ciklusa pomoću javax.annotation.PostConstruct bilješka.

Uz ovu napomenu, spremnik će je pozvati nakon instancije graha:

@PostConstruct javna void inicijalizacija () {Stanja popisa = novi ArrayList (); States.add ("Teksas"); States.add ("Alabama"); States.add ("Aljaska"); States.add ("Arizona"); States.add ("Arkansas"); countryStatesMap.put ("UnitedStates", države); }

5. Istodobnost

Dalje, osmislit ćemo upravljanje istodobnošću Singleton Session Bean-a. EJB pruža dvije metode za provođenje istodobnog pristupa bendu Singleton Session: istodobnost kojom se upravlja kontejnerom i istodobnost kojom upravlja grah.

Bilješka javax.ejb.ConcurrencyManagement definira politiku istodobnosti za metodu. Prema zadanim postavkama, EJB spremnik koristi istodobnost kojom upravlja spremnik.

The @ConcurrencyManagement bilješka traje a javax.ejb.ConcurrencyManagementType vrijednost. Opcije su:

  • ConcurrencyManagementType.CONTAINER za istodobnost kojom se upravlja kontejnerom.
  • ConcurrencyManagementType.BEAN za istodobnost kojom se upravlja grahom.

5.1. Konkurencija kojom upravlja kontejner

Jednostavno rečeno, u istodobnosti kojom upravlja kontejner, spremnik kontrolira kako klijentov pristup metodama.

Iskoristimo @ConcurrencyManagement bilješka s vrijednošću javax.ejb.ConcurrencyManagementType.CONTAINER:

@Singleton @Startup @ConcurrencyManagement (ConcurrencyManagementType.CONTAINER) javna klasa CountryStateContainerManagedBean implementira CountryState {...}

Upotrijebit ćemo se za određivanje razine pristupa svakoj od poslovnih metoda singletona javax.ejb.Lock bilješka. javax.ejb.LockType sadrži vrijednosti za @Lock bilješka. javax.ejb.LockType definira dvije vrijednosti:

  • LockType.WRITE - Ova vrijednost omogućuje ekskluzivno zaključavanje pozivajućeg klijenta i sprječava sve ostale klijente da pristupe svim metodama graha. Upotrijebite ovo za metode koje mijenjaju stanje zrna singleton.
  • LockType.READOva vrijednost omogućuje istodobna zaključavanja više klijenata za pristup metodi.

    Koristite ovo za metode koje samo čitaju podatke s graha.

Imajući ovo na umu, definirat ćemo setStates () metoda sa @Lock (LockType.WRITE) napomena, kako bi se spriječilo istodobno ažuriranje stanja od strane klijenata.

Da bismo klijentima omogućili istodobno čitanje podataka, napomenut ćemo getStates () s @Lock (LockType.READ):

@Singleton @Startup @ConcurrencyManagement (ConcurrencyManagementType.CONTAINER) javna klasa CountryStateContainerManagedBean implementira CountryState {private final Map

Da bismo zaustavili izvršavanje metoda na dulje vrijeme i blokirali ostale klijente na neodređeno vrijeme, koristit ćemo javax.ejb.AccessTimeout napomena o čekanju dugo čekajućih poziva.

Koristiti @AccessTimeout napomena za definiranje broja vremenskih isteka metode u milisekundama. Nakon isteka vremena spremnik baca a javax.ejb.ConcurrentAccessTimeoutException a izvršenje metode prestaje.

5.2. Istodobnost kojom upravlja grah

U istodobnosti kojom upravlja Bean, spremnik ne kontrolira simultani pristup klijenta Singleton Session Beanu. Razvojni programer mora sam implementirati istodobnost.

Ako programer ne implementira paralelnost, sve su metode istovremeno dostupne svim klijentima. Java nudi sinkronizacija i hlapljiv primitivi za provedbu paralelnosti.

Da biste saznali više o istodobnosti, pročitajte više java.util.concurrent ovdje i atomske varijable ovdje.

Za istodobnost kojom se upravlja grahom, definirajmo @ConcurrencyManagement napomena uz javax.ejb.ConcurrencyManagementType.BEAN vrijednost za klasu Singleton Session Bean:

@Singleton @Startup @ConcurrencyManagement (ConcurrencyManagementType.BEAN) javna klasa CountryStateBeanManagedBean implementira CountryState {...}

Dalje ćemo napisati setStates () metoda koja mijenja stanje zrna pomoću sinkronizirano ključna riječ:

javna sinkronizirana praznina setStates (država niza, stanja popisa) {countryStatesMap.put (država, države); }

The sinkronizirano Ključna riječ čini metodu dostupnom samo po jednoj niti istovremeno.

The getStates () metoda ne mijenja stanje Bean-a i zato ne treba koristiti sinkronizirano ključna riječ.

6. Klijent

Sada možemo pisati klijentu da pristupi našem Singleton Session Beanu.

Session Bean možemo rasporediti na poslužiteljima spremnika aplikacija kao što su JBoss, Glassfish itd. Kako bi stvari bile jednostavne, koristit ćemo javax.ejb.embedded.EJBContainer razred. EJBCkontejner radi u istom JVM-u kao i klijent i pruža većinu usluga poslovnog spremnika za grah.

Prvo ćemo stvoriti primjerak EJBCkontejner. Ova instanca spremnika pretražit će i inicijalizirati sve EJB module koji su prisutni u putu predavanja:

javna klasa CountryStateCacheBeanTest {private EJBContainer ejbContainer = null; privatni kontekst konteksta = null; @Prije javnog void init () {ejbContainer = EJBContainer.createEJBContainer (); context = ejbContainer.getContext (); }}

Dalje, dobit ćemo javax.naming.Kontekst objekt iz inicijaliziranog objekta spremnika. Koristiti Kontekst Primjerice, možemo dobiti referencu na CountryStateContainerManagedBean i pozovite metode:

@Test public void whenCallGetStatesFromContainerManagedBean_ReturnsStatesForCountry () baca izuzetak {String [] očekujeStates = {"Texas", "Alabama", "Alaska", "Arizona", "Arkansas"}; CountryState countryStateBean = (CountryState) kontekst .lookup ("java: global / singleton-ejb-bean / CountryStateContainerManagedBean"); Navesti stvarne države = countryStateBean.getStates ("UnitedStates"); assertNotNull (actualStates); assertArrayEquals (očekuje seStates, actualStates.toArray ()); } @Test public void whenCallSetStatesFromContainerManagedBean_SetsStatesForCountry () baca izuzetak {String [] očekujeStates = {"California", "Florida", "Hawaii", "Pennsylvania", "Michigan"}; CountryState countryStateBean = (CountryState) kontekst .lookup ("java: global / singleton-ejb-bean / CountryStateContainerManagedBean"); countryStateBean.setStates ("UnitedStates", Arrays.asList (očekuje se Država)); Navesti stvarne države = countryStateBean.getStates ("UnitedStates"); assertNotNull (actualStates); assertArrayEquals (očekuje seStates, actualStates.toArray ()); }

Slično tome, možemo koristiti Kontekst instance da biste dobili referencu za Bean-Managed Singleton Bean i pozvali odgovarajuće metode:

@Test public void whenCallGetStatesFromBeanManagedBean_ReturnsStatesForCountry () baca izuzetak {String [] očekujeStates = {"Texas", "Alabama", "Alaska", "Arizona", "Arkansas"}; CountryState countryStateBean = (CountryState) kontekst .lookup ("java: global / singleton-ejb-bean / CountryStateBeanManagedBean"); Navesti stvarne države = countryStateBean.getStates ("UnitedStates"); assertNotNull (actualStates); assertArrayEquals (očekuje seStates, actualStates.toArray ()); } @Test public void whenCallSetStatesFromBeanManagedBean_SetsStatesForCountry () baca izuzetak {String [] očekujeStates = {"California", "Florida", "Hawaii", "Pennsylvania", "Michigan"}; CountryState countryStateBean = (CountryState) kontekst .lookup ("java: global / singleton-ejb-bean / CountryStateBeanManagedBean"); countryStateBean.setStates ("UnitedStates", Arrays.asList (očekuje se Država)); Navesti stvarne države = countryStateBean.getStates ("UnitedStates"); assertNotNull (actualStates); assertArrayEquals (očekuje seStates, actualStates.toArray ()); }

Završite naša ispitivanja zatvaranjem EJBCkontejner u Zatvoriti() metoda:

@Nakon javne praznine close () {if (ejbContainer! = Null) {ejbContainer.close (); }}

7. Zaključak

Singleton sesijski grah jednako je fleksibilan i moćan kao i svaki standardni sesijski grah, ali dopušta nam da primijenimo Singleton uzorak za dijeljenje stanja među klijentima naše aplikacije.

Upravljanje paralelnošću Singleton Bean-a moglo bi se jednostavno implementirati pomoću Container-Managed Concurrency-a, gdje spremnik brine o istodobnom pristupu više klijenata, ili biste također mogli implementirati vlastito prilagođeno upravljanje paralelnošću koristeći Bean-Managed Concurrency.

Izvorni kod ovog vodiča možete pronaći na GitHubu.


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