Razlika između CDI i EJB Singleton

1. Pregled

U ovom uputstvu pobliže ćemo pogledati dvije vrste pojedinačnih zvukova dostupnih u Jakarta EE. Objasnit ćemo i demonstrirati razlike i vidjeti primjere prikladne za svaku od njih.

Prvo, hajde da vidimo o čemu se radi kod singletona prije nego što ulazimo u detalje.

2. Jednokračni uzorak dizajna

Prisjetimo se da je uobičajeni način implementacije jednobojnog uzorka statička instanca i privatni konstruktor:

javna konačna klasa Singleton {privatna statička konačna instanca Singleton = novi Singleton (); private Singleton () {} javni statički Singleton getInstance () {return instanca; }} 

Ali, nažalost, ovo zapravo nije objektno orijentirano. Ima i nekoliko problema s više niti.

CDI i EJB spremnici ipak nam daju objektno orijentiranu alternativu.

3. CDI Singleton

Uz CDI (konteksti i ubrizgavanje ovisnosti) lako možemo stvoriti pojedinačne ekrane pomoću @Singleton bilješka. Ova je napomena dio javax.injekt paket. Upućuje spremnik da instancirajte singleton jednom i prenosi referencu na druge predmete tijekom injekcije.

Kao što vidimo, jednokratna implementacija s CDI je vrlo jednostavna:

@Singleton javna klasa CarServiceSingleton {// ...} 

Naš razred simulira servis automobila. Imamo puno različitih slučajeva Automobils, ali svi koriste istu trgovinu za servisiranje. Stoga, Singleton dobro pristaje.

Možemo provjeriti radi li se o istoj instanci jednostavnim JUnit testom koji dva puta traži kontekst za klasu. Imajte na umu da imamo getBean ovdje je pomoćna metoda za čitljivost:

@Test javna praznina givenASingleton_whenGetBeanIsCalledTwice_thenTheSameInstanceIsReturned () {CarServiceSingleton one = getBean (CarServiceSingleton.class); CarServiceSingleton dva = getBean (CarServiceSingleton.class); assertTrue (jedan == dva); } 

Zbog @Singleton napomena, spremnik će oba puta vratiti istu referencu. Ako ovo pokušamo s običnim upravljanim grahom, spremnik će svaki put pružiti drugu instancu.

I dok ovo djeluje jednako i za jedno i za drugo javax.injekt.Singleton ili javax.ejb.Singleton, postoji ključna razlika između ove dvije.

4. EJB Singleton

Da bismo stvorili EJB singleton koristimo @Singleton napomena iz javax.ejb paket. Na ovaj način stvaramo Singleton Session Bean.

Ovu implementaciju možemo testirati na isti način na koji smo testirali CDI implementaciju u prethodnom primjeru, a rezultat će biti isti. EJB singletoni, kako se očekivalo, pružaju jedinstveni primjerak klase.

Međutim, EJB Singletons također pružaju dodatne funkcije u obliku kontrole istodobnosti kojom upravlja kontejner.

Kada koristimo ovu vrstu implementacije, EJB spremnik osigurava pristup svakoj javnoj metodi klase odjednom s jednom niti. Ako više niti pokušava pristupiti istoj metodi, samo jedna nit će je moći koristiti dok druge čekaju svoj red.

To ponašanje možemo provjeriti jednostavnim testom. Uvest ćemo simulaciju reda usluga za naše pojedinačne klase:

privatni statički int serviceQueue; javna int služba (automobil automobila) {serviceQueue ++; Navoj.spavanje (100); car.setServiced (true); serviceQueue--; return serviceQueue; } 

Red za uslugu implementiran je kao obični statički cijeli broj koji se povećava kada automobil "uđe" u uslugu, a smanjuje se kad "napusti". Ako spremnik osigurava pravilno zaključavanje, ta bi varijabla trebala biti jednaka nuli prije i nakon usluge, a jednaka jedinici tijekom usluge.

To ponašanje možemo provjeriti jednostavnim 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 (novi automobil ("Speedster") xyz ")); assertEquals (0, serviceQueue);}}). start (); } povratak; } 

Ovaj test započinje 10 paralelnih niti. Svaka nit instancira automobil i pokušava ga servisirati. Nakon usluge tvrdi da je vrijednost datoteke Red za uslugu se vratio na nulu.

Ako, na primjer, izvršimo sličan test na CDI singletonu, naš test neće uspjeti.

5. Zaključak

U ovom smo članku prošli kroz dvije vrste singleton implementacija dostupnih u Jakarti EE. Vidjeli smo njihove prednosti i nedostatke, a također smo pokazali kako i kada koristiti svaku od njih.

I kao i uvijek do danas, cjeloviti izvorni kod dostupan je na GitHubu.


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