A különbség a CDI és az EJB Singleton között

1. Áttekintés

Ebben az oktatóanyagban közelebbről megvizsgáljuk a Jakarta EE-ben elérhető kétféle szingulettet. Megmagyarázzuk és bemutatjuk a különbségeket, és megnézzük a megfelelő felhasználási módokat.

Először nézzük meg, mi a szingulettek lényege, mielőtt belemerülnénk a részletekbe.

2. Singleton Design Pattern

Emlékezzünk arra, hogy a Singleton Pattern megvalósításának általános módja egy statikus példány és egy privát konstruktor:

public final class Singleton {private static final Singleton instance = new Singleton (); privát Singleton () {} nyilvános statikus Singleton getInstance () {return instance; }} 

De sajnos ez nem igazán objektum-orientált. És van néhány szálon keresztüli problémája.

A CDI és az EJB konténerek azonban objektum-orientált alternatívát kínálnak.

3. CDI Singleton

A CDI (Contexts and Dependency Injection) segítségével könnyen létrehozhatunk szinguletteket a @Szingli annotáció. Ez az annotáció a javax.injekció csomag. Arra utasítja a konténert példányozza egyszer a szingulettet és az injekció során átadja referenciáját más tárgyakra.

Mint láthatjuk, a CDI-vel történő szimpla megvalósítás nagyon egyszerű:

@Singleton nyilvános osztály CarServiceSingleton {// ...} 

Osztályunk autószervizt szimulál. Nagyon sokféle változatunk van Autós, de mindannyian ugyanazt a boltot használják szervizelésre. Ezért Singleton jól illik.

Egy egyszerű JUnit teszttel ellenőrizhetjük, hogy ugyanaz a példány van-e, amely kétszer kéri az osztály kontextusát. Ne feledje, hogy van egy getBean segítő módszer itt az olvashatóság érdekében:

@Test public void givenASingleton_whenGetBeanIsCalledTwice_thenTheSameInstanceIsReturned () {CarServiceSingleton one = getBean (CarServiceSingleton.class); CarServiceSingleton kettő = getBean (CarServiceSingleton.class); assertTrue (egy == kettő); } 

A @Szingli megjegyzés, a tároló mindkét alkalommal ugyanazt a hivatkozást adja vissza. Ha ezt egy sima kezelt babgal próbáljuk meg, akkor a tároló minden alkalommal más példányt fog biztosítani.

És bár ez mindkét esetben ugyanúgy működik javax.inject.Singleton vagy javax.ejb.Singleton, van egy fő különbség e kettő között.

4. EJB Singleton

Az EJB szinglet létrehozásához a @Szingli kommentár a javax.ejb csomag. Így létrehozunk egy Singleton Session babot.

Ezt a megvalósítást ugyanúgy tesztelhetjük, mint az előző példában a CDI implementációt, és az eredmény ugyanaz lesz. Az EJB szinglettjei a várakozásoknak megfelelően biztosítják az osztály egyetlen példányát.

Azonban, Az EJB Singletons kiegészítő funkciókat is nyújt a konténer által kezelt párhuzamosság-ellenőrzés formájában.

Amikor ilyen típusú megvalósítást alkalmazunk, az EJB tároló biztosítja, hogy az osztály minden nyilvános módszeréhez egyszerre egyetlen szál férjen hozzá. Ha több szál megpróbálja elérni ugyanazt a módszert, csak egy szál fogja használni, míg mások várják a sorukat.

Egy egyszerű teszt segítségével ellenőrizhetjük ezt a viselkedést. Bemutatjuk a szolgáltatási várakozási szimulációt az egyes osztályaink számára:

privát statikus int serviceQueue; public int service (Car car) {serviceQueue ++; Szál.alszik (100); car.setServiced (true); serviceQueue--; return serviceQueue; } 

serviceQueue sima statikus egész számként valósul meg, amely növekszik, amikor egy autó „belép” a szolgáltatásba, és csökken, amikor „elhagyja”. Ha a konténer biztosítja a megfelelő reteszelést, ennek a változónak nullának kell lennie a szolgáltatás előtt és után, és egyenlőnek kell lennie a szerviz során.

Egy egyszerű teszt segítségével ellenőrizhetjük ezt a viselkedést:

@Test public void whenEjb_thenLockingIsProvided () {for (int i = 0; i <10; i ++) {new Thread (new Runnable () {@Orride public void run () {int serviceQueue = carServiceEjbSingleton.service (new Car ("Speedster) xyz ")); assertEquals (0, serviceQueue);}}). start (); } Visszatérés; } 

Ez a teszt 10 párhuzamos szálat indít el. Minden szál példányosítja az autót és megpróbálja szervizelni. A szolgáltatás után azt állítja, hogy a serviceQueue visszaáll a nullára.

Ha például hasonló tesztet hajtunk végre a CDI szinguletten, akkor tesztünk sikertelen lesz.

5. Következtetés

Ebben a cikkben a Jakarta EE-ben elérhető kétféle szingleton megvalósításon esett át. Láttuk előnyeiket és hátrányaikat, valamint bemutattuk, hogyan és mikor kell használni mindegyiket.

És mint mindig, a teljes forráskód elérhető a GitHubon.