Rozdiel medzi CDI a EJB Singleton

1. Prehľad

V tomto tutoriáli sa bližšie pozrieme na dva typy singletonov dostupných v Jakarte EE. Vysvetlíme a demonštrujeme rozdiely a uvidíme spôsoby použitia vhodné pre každý z nich.

Najprv sa pozrime, o čom sú singletony, a až potom sa rozoberieme podrobnejšie.

2. Dizajnový vzor Singleton

Pripomeňme, že bežným spôsobom implementácie Singletonovho vzoru je statická inštancia a súkromný konštruktor:

verejná finálna trieda Singleton {súkromná statická konečná inštancia Singleton = nový Singleton (); private Singleton () {} public static Singleton getInstance () {return instance; }} 

Ale, bohužiaľ, to nie je v skutočnosti objektové. A má niekoľko problémov s viacerými vláknami.

Kontajnery CDI a EJB nám však poskytujú objektovo orientovanú alternatívu.

3. CDI Singleton

S CDI (kontexty a závislosť vstrekovania), môžeme ľahko vytvoriť singletons pomocou @Singleton anotácia. Táto anotácia je súčasťou javax.inject balíček. Dáva kontajneru pokyn inštanciu singletonu vykonajte raz a počas vstrekovania odovzdá svoj odkaz na ďalšie objekty.

Ako vidíme, implementácia singletonu pomocou CDI je veľmi jednoduchá:

@Singleton verejná trieda CarServiceSingleton {// ...} 

Naša trieda simuluje autoservis. Máme veľa rôznych prípadov Autos, ale všetci používajú na servis rovnaký obchod. Preto je Singleton vhodný.

Môžeme overiť, že ide o rovnakú inštanciu pomocou jednoduchého testu JUnit, ktorý sa dvakrát pýta na kontext triedy. Všimnite si, že máme getBean pomocná metóda pre čitateľnosť:

@Test public void givenASingleton_whenGetBeanIsCalledTwice_thenTheSameInstanceIsReturned () {CarServiceSingleton one = getBean (CarServiceSingleton.class); CarServiceSingleton two = getBean (CarServiceSingleton.class); assertTrue (jeden == dva); } 

Z dôvodu @Singleton anotácie, kontajner vráti obidve rovnaké referencie. Ak to skúsime s obyčajným spravovaným objektom bean, kontajner poskytne zakaždým inú inštanciu.

A zatiaľ čo to funguje rovnako pre obidve javax.inject.Singleton alebo javax.ejb.Singleton, medzi týmito dvoma je zásadný rozdiel.

4. EJB Singleton

Na vytvorenie singleponu EJB používame @Singleton anotácia z javax.ejb balíček. Týmto spôsobom vytvoríme Singleton Session Bean.

Túto implementáciu môžeme otestovať rovnakým spôsobom, ako sme testovali implementáciu CDI v predchádzajúcom príklade, a výsledok bude rovnaký. Singletons EJB, ako sa dalo očakávať, poskytujú jednu inštanciu triedy.

Avšak EJB Singletons tiež poskytujú ďalšie funkcie vo forme riadenia súbežnosti riadeného kontajnerom.

Keď používame tento typ implementácie, kontajner EJB zaručuje, že ku každej verejnej metóde triedy je prístupné vždy iba jedným vláknom. Ak sa viac vlákien pokúsi získať prístup k tej istej metóde, použije ju iba jedno vlákno, zatiaľ čo ostatné čakajú na svoju príležitosť.

Toto správanie môžeme overiť jednoduchým testom. Pre naše triedy singleton zavedieme simuláciu frontu služieb:

private static int serviceQueue; public int service (Car car) {serviceQueue ++; Závit. Spánok (100); car.setServiced (true); serviceQueue--; návrat serviceQueue; } 

serviceQueue je implementované ako obyčajné statické celé číslo, ktoré sa zvyšuje, keď auto „vstúpi“ do služby, a zníži sa, keď „vozidlo“ opustí. Ak je kontajner zaistený správnym zaistením, táto premenná by sa mala pred a po podaní rovnať nule a počas služby by sa mala rovnať jednej.

Toto správanie môžeme skontrolovať jednoduchým testom:

@Test public void whenEjb_thenLockingIsProvided () {for (int i = 0; i <10; i ++) {new Thread (new Runnable () {@Override public void run () {int serviceQueue = carServiceEjbSingleton.service (new Car ("Speedster xyz ")); assertEquals (0, serviceQueue);}}). start (); } návrat; } 

Tento test začína 10 paralelných vlákien. Každé vlákno vytvorí inštanciu automobilu a pokúsi sa ho opraviť. Po vykonaní služby tvrdí, že hodnota serviceQueue je späť na nule.

Ak napríklad vykonáme podobný test na singli CDI, náš test zlyhá.

5. Záver

V tomto článku sme prešli dvoma typmi singletonových implementácií dostupných v Jakarta EE. Videli sme ich výhody a nevýhody a tiež sme demonštrovali, ako a kedy ich používať.

Kompletný zdrojový kód je ako vždy k dispozícii na GitHub.


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