Singleton Session Bean v Jakarte EE

1. Prehľad

Kedykoľvek sa pre daný prípad použitia vyžaduje jedna inštancia relácie Bean, môžeme použiť reláciu Singleton Bean.

V tomto výučbe to preskúmame na príklade s aplikáciou Jakarta EE.

2. Maven

Najskôr je potrebné definovať požadované závislosti Maven v pom.xml.

Definujme závislosti pre EJB API a Embedded EJB kontajner pre nasadenie EJB:

 javax javaee-api 8.0 za predpokladu org.apache.openejb tomee-embedded 1.7.5 

Najnovšie verzie nájdete v Maven Central na rozhraniach JavaEE API a tomEE.

3. Druhy fazule session

Existujú tri typy session beanov. Predtým, ako preskúmame fazuľa Singleton Session Beans, pozrime sa, aký je rozdiel medzi životnými cyklami troch typov.

3.1. Stavové fazule

Server Stateful Session Bean udržuje konverzačný stav s klientom, ktorého komunikuje.

Každý klient vytvorí novú inštanciu Stateful Bean a nie je zdieľaný s ostatnými klientmi.

Keď sa komunikácia medzi klientom a fazuľou skončí, relácia Bean sa tiež ukončí.

3.2. Fazuľa bez štátnej príslušnosti

Bean bez štátnej príslušnosti neudržiava s klientom žiadny konverzačný stav. Fazuľa obsahuje stav špecifický pre klienta iba do doby vyvolania metódy.

Následné vyvolanie metódy je na rozdiel od Stateean Session Bean nezávislé.

Kontajner udržuje skupinu bezstavových fazúľ a tieto inštancie je možné zdieľať medzi viacerými klientmi.

3.3. Fazuľa Singleton Session Beans

Bean Singleton Session Bean udržuje stav fazule po celý životný cyklus aplikácie.

Bean Singleton Session Beans je obdobou Bean bez štátnej príslušnosti, ale v celej aplikácii je vytvorená iba jedna inštancia Bean Singleton Session Bean, ktorá sa neukončí, kým sa aplikácia nevypne.

Jedna inštancia objektu bean je zdieľaná medzi viacerými klientmi a je k nej možné súčasne pristupovať.

4. Vytvorenie fazule Singleton Session Bean

Začnime tým, že pre to vytvoríme rozhranie.

Pre tento príklad použijeme javax.ejb.Miestne anotácia na definovanie rozhrania:

@ Miestne miestne rozhranie CountryState {List getStates (krajina reťazca); void setStates (krajina reťazca, štáty zoznamu); }

Použitím @ Miestne znamená, že k fazuli je prístupný v rámci tej istej aplikácie. Máme tiež možnosť použiť javax.ejb.Vzdialené anotácia, ktorá nám umožňuje volať na EJB na diaľku.

Teraz definujeme implementačnú triedu EJB bean. Triedu označíme ako Singleton Session Bean pomocou anotácie javax.ejb.Singleton.

Okrem toho si fazuľu označíme aj javaxom.ejb.Startovanie anotácia, ktorá informuje kontajner EJB o inicializácii fazule pri štarte:

@Singleton @Startup verejná trieda CountryStateContainerManagedBean implementuje CountryState {...}

Tomu sa hovorí nedočkavá inicializácia. Ak nepoužívame @Začiatok, kontajner EJB určuje, kedy má byť fazuľa inicializovaná.

Môžeme tiež definovať viac fazule Session na inicializáciu údajov a načítanie fazule v konkrétnom poradí. Preto použijeme, javax.ejb.DependsOn anotácia, ktorá definuje závislosť našej fazule od ostatných fazúľ relácie.

Hodnota pre @Záleží na anotácia je pole mien názvov tried Bean, od ktorých náš Bean závisí:

@Singleton @Startup @DependsOn ({"DependentBean1", "DependentBean2"}) verejná trieda CountryStateCacheBean implementuje CountryState {...}

Definujeme inicializovať () metóda, ktorá inicializuje fazuľa, a robí ju metódou spätného volania životného cyklu pomocou javax.annotation.PostConstruct anotácia.

S touto anotáciou ju kontajner zavolá po vytvorení inštancie fazule:

@PostConstruct public void initialize () {List states = new ArrayList (); States.add ("Texas"); States.add ("Alabama"); States.add ("Aljaška"); States.add („Arizona“); States.add („Arkansas“); countryStatesMap.put ("UnitedStates", štáty); }

5. Súbežnosť

Ďalej navrhneme správu súbežnosti Singleton Session Bean. EJB poskytuje dve metódy implementácie súbežného prístupu k relácii Bean Singleton: súbežnosť riadená kontajnerom a súbežnosť spravovaná Beanom.

Anotácia javax.ejb.ConcurrencyManagement definuje politiku súbežnosti pre metódu. Kontajner EJB štandardne používa súbežnosť spravovanú kontajnerom.

The @ConcurrencyManagement anotácia trvá a javax.ejb.ConcurrencyManagementType hodnotu. Možnosti sú:

  • ConcurrencyManagementType.CONTAINER pre súbežnosť spravovanú kontajnerom.
  • ConcurrencyManagementType.BEAN pre súbežnosť spravovanú fazuľou.

5.1. Kontajnerom riadená súbežnosť

Jednoducho povedané, v súbežnosti spravovanej kontajnerom kontajner riadi prístup klientov k metódam.

Použime @ConcurrencyManagement anotácia s hodnotou javax.ejb.ConcurrencyManagementType.CONTAINER:

@Singleton @Startup @ConcurrencyManagement (ConcurrencyManagementType.CONTAINER) verejná trieda CountryStateContainerManagedBean implementuje CountryState {...}

Na určenie úrovne prístupu ku každej z obchodných metód jednotlivca použijeme javax.ejb.Lock anotácia. javax.ejb.LockType obsahuje hodnoty pre @Lock anotácia. javax.ejb.LockType definuje dve hodnoty:

  • LockType.WRITE - Táto hodnota poskytuje výlučný zámok volajúcemu klientovi a bráni všetkým ostatným klientom v prístupe ku všetkým metódam fazule. Toto použite pre metódy, ktoré menia stav singletonovej fazule.
  • LockType.READTáto hodnota poskytuje súbežné zámky viacerým klientom na prístup k metóde.

    Toto použite pre metódy, ktoré iba čítajú údaje z fazule.

V tejto súvislosti definujeme setStates () metóda s @Lock (LockType.WRITE) anotácia, aby sa zabránilo súčasnej aktualizácii stavu klientmi.

Aby sme umožnili klientom súbežne čítať údaje, urobíme anotáciu getStates () s @Lock (LockType.READ):

@Singleton @Startup @ConcurrencyManagement (ConcurrencyManagementType.CONTAINER) verejná trieda CountryStateContainerManagedBean implementuje CountryState {súkromná konečná mapa

Aby sme zastavili vykonávanie metód na dlhú dobu a blokovanie ďalších klientov na neurčito, použijeme javax.ejb.AccessTimeout anotácia na vypršanie časového limitu dlho čakajúcich hovorov.

Použi @AccessTimeout anotácia na definovanie časového limitu metódy v milisekundách. Po uplynutí časového limitu hodí kontajner a javax.ejb.ConcurrentAccessTimeoutException a vykonávanie metódy sa ukončí.

5.2. Beanom riadená súbežnosť

V spravovanej súbežnosti Bean kontajner nekontroluje simultánny prístup klientov k relácii Singleton Session Bean. Developer je povinný implementovať súbežnosť sám.

Pokiaľ vývojár neimplementuje súbežnosť, všetky metódy sú prístupné všetkým klientom súčasne. Java poskytuje synchronizácia a prchavý primitívy na implementáciu súbežnosti.

Ak sa chcete dozvedieť viac informácií o súbežnosti, prečítajte si o java.util.concurrent tu a atómové premenné tu.

Pre súbežnosť spravovanú fazuľou definujme @ConcurrencyManagement anotácia s javax.ejb.ConcurrencyManagementType.BEAN hodnota pre triedu Singleton Session Bean:

@Singleton @Startup @ConcurrencyManagement (ConcurrencyManagementType.BEAN) verejná trieda CountryStateBeanManagedBean implementuje CountryState {...}

Ďalej napíšeme setStates () metóda, ktorá mení stav fazule pomocou synchronizované kľúčové slovo:

verejné synchronizované neplatné setStates (krajina reťazca, štáty zoznamu) {countryStatesMap.put (krajina, štáty); }

The synchronizované kľúčové slovo sprístupňuje metódu súčasne iba jedným vláknom.

The getStates () metóda nezmení stav Beanu a preto nemusí používať synchronizované kľúčové slovo.

6. Klient

Teraz môžeme napísať klientovi prístup k nášmu Singleton Session Bean.

Session Bean môžeme nasadiť na aplikačné kontajnerové servery ako JBoss, Glassfish atď. Pre zjednodušenie použijeme javax.ejb.embedded.EJBContainer trieda. EJBContainer beží v rovnakom prostredí JVM ako klient a poskytuje väčšinu služieb kontajnera Enterprise Bean.

Najskôr vytvoríme inštanciu EJBContainer. Táto inštancia kontajnera prehľadá a inicializuje všetky moduly EJB prítomné v ceste triedy:

public class CountryStateCacheBeanTest {private EJBContainer ejbContainer = null; private Context context = null; @ Pred public void init () {ejbContainer = EJBContainer.createEJBContainer (); kontext = ejbContainer.getContext (); }}

Ďalej dostaneme javax.naming.Context objekt z inicializovaného kontajnerového objektu. Pomocou Kontext napríklad môžeme získať odkaz na CountryStateContainerManagedBean a zavolajte metódy:

@Test public void whenCallGetStatesFromContainerManagedBean_ReturnsStatesForCountry () hodí výnimku {String [] expectStates = {"Texas", "Alabama", "Aljaška", "Arizona", "Arkansas"}; CountryState countryStateBean = (CountryState) context .lookup ("java: global / singleton-ejb-bean / CountryStateContainerManagedBean"); Zoznam aktualnych statov = countryStateBean.getStates ("UnitedStates"); assertNotNull (actualStates); assertArrayEquals (expectStates, actualStates.toArray ()); } @Test public void whenCallSetStatesFromContainerManagedBean_SetsStatesForCountry () throws Exception {String [] expectStates = {"California", "Florida", "Hawaii", "Pennsylvania", "Michigan"}; CountryState countryStateBean = (CountryState) context .lookup ("java: global / singleton-ejb-bean / CountryStateContainerManagedBean"); countryStateBean.setStates ("UnitedStates", Arrays.asList (expectStates)); Zoznam aktualnych statov = countryStateBean.getStates ("UnitedStates"); assertNotNull (actualStates); assertArrayEquals (expectStates, actualStates.toArray ()); }

Podobne môžeme použiť Kontext napríklad získať referenciu pre Bean-Managed Singleton Bean a zavolať príslušné metódy:

@Test public void whenCallGetStatesFromBeanManagedBean_ReturnsStatesForCountry () vyvolá výnimku {String [] expectStates = {"Texas", "Alabama", "Aljaška", "Arizona", "Arkansas"}; CountryState countryStateBean = (CountryState) context .lookup ("java: global / singleton-ejb-bean / CountryStateBeanManagedBean"); Zoznam aktualnych statov = countryStateBean.getStates ("UnitedStates"); assertNotNull (actualStates); assertArrayEquals (expectStates, actualStates.toArray ()); } @Test public void whenCallSetStatesFromBeanManagedBean_SetsStatesForCountry () throws Exception {String [] expectStates = {"California", "Florida", "Hawaii", "Pennsylvania", "Michigan"}; CountryState countryStateBean = (CountryState) context .lookup ("java: global / singleton-ejb-bean / CountryStateBeanManagedBean"); countryStateBean.setStates ("UnitedStates", Arrays.asList (expectStates)); Zoznam aktualnych statov = countryStateBean.getStates ("UnitedStates"); assertNotNull (actualStates); assertArrayEquals (expectStates, actualStates.toArray ()); }

Naše testy ukončíme uzavretím EJBContainer v Zavrieť() metóda:

@ Po public void close () {if (ejbContainer! = Null) {ejbContainer.close (); }}

7. Záver

Fazuľa Singleton Session Beans je rovnako flexibilná a výkonná ako ktorákoľvek štandardná fľaša Session Bean, ale umožňuje nám použiť Singletonov model na zdieľanie stavu medzi klientmi našej aplikácie.

Správa súbežnosti Singleton Bean sa dá ľahko implementovať pomocou Container-Managed Concurrency, kde sa kontajner stará o súčasný prístup viacerých klientov, alebo môžete tiež implementovať svoju vlastnú správu súbežnosti pomocou Bean-Managed Concurrency.

Zdrojový kód tohto tutoriálu nájdete na GitHub.


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