Singleton Session Bean, Jakarta EE

1. Áttekintés

Amikor egy munkamag egyetlen példányára van szükség egy adott felhasználási esethez, használhatunk egy Singleton munkamenet babot.

Ebben az oktatóanyagban ezt egy példa segítségével fogjuk feltárni egy Jakarta EE alkalmazással.

2. Maven

Először is meg kell határoznunk a szükséges Maven-függőségeket a pom.xml.

Határozzuk meg az EJB API-k és a beágyazott EJB-tároló függőségeit az EJB telepítéséhez:

 javax javaee-api 8.0 feltéve org.apache.openejb tomee-embedded 1.7.5 

A legújabb verziók megtalálhatók a Maven Central webhelyen, a JavaEE API-n és a tomEE-n.

3. A szekció bab típusai

A Session bab háromféle lehet. Mielőtt felfedeznénk a Singleton Session Bean-t, nézzük meg, mi a különbség a három típus életciklusa között.

3.1. Állapotban lévő munkabab

A Stateful Session Bean fenntartja a beszélgetési állapotot az ügyféllel, akit kommunikál.

Minden ügyfél létrehoz egy új Stateful Bean példányt, és nincs megosztva más ügyfelekkel.

Amikor az ügyfél és a bab közötti kommunikáció véget ér, a Session Bean is megszűnik.

3.2. Hontalan munkamenet bab

A hontalan munkamenet bab nem tart fenn semmilyen beszélgetési állapotot az ügyféllel. A bab csak a kliens specifikus állapotát tartalmazza a metódus meghívásának időtartamáig.

Az egymást követő módszer-invokációk függetlenek a Stateful Session Bean-től.

A tároló egy hontalan babot tárol, és ezeket az eseteket több ügyfél is megoszthatja.

3.3. Singleton Session bab

A Singleton Session Bean fenntartja a bab állapotát az alkalmazás teljes életciklusáig.

A Singleton Session Bean hasonló a hontalan Session Bean-hoz, de a Singleton Session Bean csak egy példánya jön létre az egész alkalmazásban, és nem fejeződik be, amíg az alkalmazást nem állítják le.

A bab egyetlen példányát több kliens osztja meg, és egyidejűleg elérhető.

4. Singleton Session Bean létrehozása

Kezdjük azzal, hogy létrehozunk egy interfészt hozzá.

Ehhez a példához használjuk a javax.ejb.Helyi annotáció az interfész meghatározásához:

@ Helyi nyilvános felület CountryState {list getStates (String country); void setStates (Sztring ország, Lista állapotok); }

Használata @Helyi azt jelenti, hogy a babot ugyanazon alkalmazáson belül érik el. Lehetőségünk van a használatra is javax.ejb.Távoli megjegyzés, amely lehetővé teszi számunkra, hogy távolról hívjuk az EJB-t.

Most meghatározzuk az EJB bab osztályát. Az osztályt Singleton Session Bean néven jelöljük a javax annotáció segítségével.ejb.Singleton.

Ezen kívül jelöljük meg a babot is a javaxszal.ejb.Kezdés kommentár az EJB konténer tájékoztatásához a bab inicializálásához az indításkor:

@Singleton @Startup public class A CountryStateContainerManagedBean megvalósítja a CountryState-t {...}

Ezt hívják buzgó inicializálásnak. Ha nem használjuk @Üzembe helyezés, az EJB konténer meghatározza, hogy mikor kell inicializálni a babot.

Több Session babot is meghatározhatunk az adatok inicializálásához és a babok beillesztéséhez a meghatározott sorrendben. Ezért használjuk, javax.ejb.DependsOn annotáció, hogy meghatározzuk babunk függőségét a többi munkababtól.

A. Értéke @Attól függ az annotáció a Bean osztálynevek tömbje, melyektől függ a Bean:

@Singleton @Startup @DependsOn ({"DependentBean1", "DependentBean2"}) public class CountryStateCacheBean megvalósítja CountryState {...}

Meghatározzuk a inicializálás () metódus, amely inicializálja a babot, és életciklusos visszahívási módszerré teszi javax.annotation.PostConstruct annotáció.

Ezzel a megjegyzéssel a konténer felhívja a bab szemrevételezésével:

@PostConstruct public void inicializálás () {List állapotok = új ArrayList (); államok.add ("Texas"); államok.add ("Alabama"); államok.add ("Alaszka"); államok.add ("Arizona"); államok.add ("Arkansas"); countryStatesMap.put ("UnitedStates", államok); }

5. Egyidejűség

Ezután megtervezzük a Singleton Session Bean párhuzamosság-kezelését. Az EJB két módszert kínál a Singleton Session Bean párhuzamos hozzáférésének megvalósítására: Konténer által kezelt egyidejűség és Bean által kezelt egyidejűség.

Az annotáció javax.ejb.ConcurrencyManagement meghatározza a módszer párhuzamossági politikáját. Alapértelmezés szerint az EJB tároló a tároló által kezelt egyidejűséget használja.

A @ConcurrencyManagement az annotáció a javax.ejb.ConcurrencyManagementType érték. A lehetőségek a következők:

  • ConcurrencyManagementType.CONTAINER konténer által kezelt párhuzamosság esetén.
  • ConcurrencyManagementType.BEAN a bab által kezelt párhuzamosságra.

5.1. Konténer által kezelt párhuzamosság

Egyszerűen fogalmazva, a konténer által kezelt párhuzamosságban a tároló ellenőrzi, hogy az ügyfelek hogyan férhetnek hozzá a módszerekhez.

Használjuk a @ConcurrencyManagement kommentár értékkel javax.ejb.ConcurrencyManagementType.CONTAINER:

@Singleton @Startup @ConcurrencyManagement (ConcurrencyManagementType.CONTAINER) public class CountryStateContainerManagedBean implementates CountryState {...}

Az egyes üzleti módszerek hozzáférési szintjének meghatározásához használjuk javax.ejb.Lock annotáció. javax.ejb.LockType a. értékeit tartalmazza @Zár annotáció. javax.ejb.LockType két értéket határoz meg:

  • LockType.WRITE - Ez az érték exkluzív zárolást biztosít a hívó kliens számára, és megakadályozza, hogy az összes többi kliens hozzáférjen a bab minden módszeréhez. Használja ezt olyan módszerekhez, amelyek megváltoztatják a szingulbab állapotát.
  • LockType.READEz az érték egyidejű zárolást biztosít több ügyfél számára a metódus eléréséhez.

    Használja ezt olyan módszerekhez, amelyek csak a babból olvasnak adatokat.

Ezt szem előtt tartva meghatározzuk a setStates () módszerrel @Lock (LockType.WRITE) megjegyzés, hogy megakadályozzák az állapot egyidejű frissítését az ügyfelek részéről.

Annak érdekében, hogy az ügyfelek egyszerre olvashassák az adatokat, jegyzetekkel ellátjuk getStates () val vel @Lock (LockType.READ):

@Singleton @Startup @ConcurrencyManagement (ConcurrencyManagementType.CONTAINER) public class CountryStateContainerManagedBean implementálja CountryState {private final Map

A metódusok hosszú ideig történő leállításához és a többi kliens korlátlan ideig történő blokkolásához a javax.ejb.AccessTimeout annotáció a régóta várakozó hívások időkorlátjához.

Használja a @AccessTimeout annotáció a milliszekundumok metódusainak számának meghatározásához. Az időtúllépés után a tároló dob a javax.ejb.ConcurrentAccessTimeoutException és a metódus végrehajtása befejeződik.

5.2. Bab által kezelt párhuzamosság

A Bean által kezelt párhuzamosság esetén a tároló nem ellenőrzi az ügyfelek által a Singleton Session Bean egyidejű hozzáférését. A fejlesztőnek önmagában kell megvalósítania a párhuzamosságot.

Hacsak a fejlesztő nem hajtja végre az egyidejűséget, az összes módszer egyszerre elérhető minden ügyfél számára. A Java biztosítja a szinkronizálás és illó primitívek a párhuzamosság megvalósításához.

Ha többet szeretne megtudni a párhuzamosságról, olvassa el java.util.egyidejű itt és az atomváltozók itt.

A bab által kezelt párhuzamosság esetén definiáljuk a @ConcurrencyManagement annotáció a javax.ejb.ConcurrencyManagementType.BEAN a Singleton Session Bean osztály értéke:

@Singleton @Startup @ConcurrencyManagement (ConcurrencyManagementType.BEAN) public class CountryStateBeanManagedBean implementálja a CountryState {...}

Ezután megírjuk a setStates () módszer, amely a bab állapotát megváltoztatja szinkronizált kulcsszó:

nyilvános szinkronizált void setStates (karakterlánc ország, listaállapotok) {countryStatesMap.put (ország, államok); }

A szinkronizált kulcsszó egyszerre csak egy szál által teszi hozzáférhetővé a módszert.

A getStates () A módszer nem változtatja meg a bab állapotát, ezért nem kell használnia a szinkronizált kulcsszó.

6. Ügyfél

Most megírhatjuk az ügyfél számára, hogy hozzáférjen a Singleton Session Bean-hez.

Telepíthetjük a Session Bean-t olyan alkalmazás-konténer szerverekre, mint a JBoss, a Glassfish stb. A dolgok egyszerűsége érdekében a javax-ot fogjuk használni..ejb.beágyazott.EJBContainer osztály. EJBContainer ugyanabban a JVM-ben fut, mint az ügyfél, és a vállalati babtartály szolgáltatásainak nagy részét biztosítja.

Először létrehozunk egy példányt EJBContainer. Ez a konténerpéldány megkeresi és inicializálja az összes EJB modult, amely az osztályútvonalon található:

public class CountryStateCacheBeanTest {private EJBContainer ejbContainer = null; private Context context = null; @A nyilvános void előtt init () {ejbContainer = EJBContainer.createEJBContainer (); context = ejbContainer.getContext (); }}

Ezután megkapjuk a javax.naming.Context objektum az inicializált tárolóobjektumból. Használni a Kontextus például megkaphatjuk a hivatkozást CountryStateContainerManagedBean és hívja meg a módszereket:

@Test public void whenCallGetStatesFromContainerManagedBean_ReturnsStatesForCountry () dobja a {String [] várt államok = {"Texas", "Alabama", "Alaska", "Arizona", "Arkansas"} kivételt; CountryState countryStateBean = (CountryState) kontextus .lookup ("java: global / singleton-ejb-bab / CountryStateContainerManagedBean"); List actualStates = countryStateBean.getStates ("UnitedStates"); assertNotNull (actualStates); assertArrayEquals (vártállapotok, ténylegesállapotok.toArray ()); } @Test public void whenCallSetStatesFromContainerManagedBean_SetsStatesForCountry () dobja a {String [] várt államok = {"Kalifornia", "Florida", "Hawaii", "Pennsylvania", "Michigan"} kivételt; CountryState countryStateBean = (CountryState) kontextus .lookup ("java: global / singleton-ejb-bab / CountryStateContainerManagedBean"); countryStateBean.setStates ("UnitedStates", Arrays.asList (várhatóStates)); List actualStates = countryStateBean.getStates ("UnitedStates"); assertNotNull (actualStates); assertArrayEquals (vártállapotok, ténylegesállapotok.toArray ()); }

Hasonlóképpen használhatjuk a Kontextus például a Bean által kezelt Singleton Bean hivatkozás megszerzéséhez, és hívja meg a megfelelő módszereket:

@Test public void whenCallGetStatesFromBeanManagedBean_ReturnsStatesForCountry () dobja a {String [] vártStates = {"Texas", "Alabama", "Alaska", "Arizona", "Arkansas"} kivételt; CountryState countryStateBean = (CountryState) kontextus .lookup ("java: global / singleton-ejb-bab / CountryStateBeanManagedBean"); List actualStates = countryStateBean.getStates ("UnitedStates"); assertNotNull (actualStates); assertArrayEquals (vártállapotok, ténylegesállapotok.toArray ()); } @Test public void whenCallSetStatesFromBeanManagedBean_SetsStatesForCountry () dobja a (z) {String [] vártStates = {"California", "Florida", "Hawaii", "Pennsylvania", "Michigan"} kivételt; CountryState countryStateBean = (CountryState) kontextus .lookup ("java: global / singleton-ejb-bab / CountryStateBeanManagedBean"); countryStateBean.setStates ("UnitedStates", Arrays.asList (várhatóStates)); List actualStates = countryStateBean.getStates ("UnitedStates"); assertNotNull (actualStates); assertArrayEquals (vártállapotok, ténylegesállapotok.toArray ()); }

Zárja le tesztjeinket a EJBContainer ban,-ben Bezárás() módszer:

@A nyilvános void bezárása után () {if (ejbContainer! = Null) {ejbContainer.close (); }}

7. Következtetés

A Singleton Session Bean ugyanolyan rugalmas és hatékony, mint bármely más Session Bean, de lehetővé teszi számunkra, hogy Singleton mintát alkalmazzunk az állapot megosztásához alkalmazásunk ügyfelei között.

A Singleton Bean egyidejű kezelése könnyen megvalósítható a Container-Managed Concurrency használatával, ahol a tároló gondoskodik több ügyfél egyidejű hozzáféréséről, vagy saját egyéni concurrency kezelését is megvalósíthatja a Bean-Managed Concurrency használatával.

Az oktatóanyag forráskódja megtalálható a GitHub oldalon.