ההבדל בין CDI ו- EJB Singleton

1. סקירה כללית

במדריך זה, אנו נסתכל מקרוב על שני סוגים של יחידים זמינים בג'קרטה EE. נסביר ונדגים את ההבדלים ונראה את השימושים המתאימים לכל אחד מהם.

ראשית, בואו נראה על מה מדובר ביחידים לפני שנכנס לפרטים.

2. תבנית עיצוב סינגלטון

נזכיר כי דרך נפוצה ליישום תבנית סינגלטון היא עם מופע סטטי ובנאי פרטי:

שיעור גמר ציבורי סינגלטון {פרטי סטטי פרטי סופי סינגלטון = סינגלטון חדש (); פרטי סינגלטון () {} ציבורי סטטי ציבורי סינגלטון getInstance () {חזרה מופע; }} 

אבל, אבוי, זה לא ממש מונחה עצמים. ויש לו כמה בעיות שרשור השחלה.

מכולות CDI ו- EJB נותנות לנו אלטרנטיבה מונחית עצמים.

3. CDI סינגלטון

באמצעות CDI (Contexts and Dependency Injection), אנו יכולים ליצור יחידים בקלות באמצעות ה- @קְלָף בּוֹדֵד ביאור. ההערה הזו היא חלק מה- javax.inject חֲבִילָה. זה מורה למכולה ליצור את הסינגל פעם אחת ומעביר את התייחסותו לאובייקטים אחרים במהלך ההזרקה.

כפי שאנו רואים, יישום יחיד עם CDI הוא פשוט מאוד:

@Singleton בכיתה הציבורית CarServiceSingleton {// ...} 

הכיתה שלנו מדמה חנות לשירותי רכב. יש לנו הרבה מקרים שונים אוטואבל כולם משתמשים באותה חנות לצורך שירות. לכן, סינגלטון מתאים מאוד.

אנו יכולים לאמת שזה אותו מקרה עם מבחן JUnit פשוט ששואל את ההקשר של הכיתה פעמיים. שים לב שיש לנו getBean שיטת עוזר כאן לקריאות:

@Test הציבור בטל שניתן ASingleton_whenGetBeanIsCalledTwice_thenTheSameInstanceIsReturned () {CarServiceSingleton one = getBean (CarServiceSingleton.class); CarServiceSingleton two = getBean (CarServiceSingleton.class); assertTrue (אחד == שניים); } 

בגלל ה @קְלָף בּוֹדֵד ביאור, המכולה תחזיר את אותה התייחסות בשתי הפעמים. אם ננסה זאת עם שעועית מנוהלת רגילה, עם זאת, המכולה תספק מופע אחר בכל פעם.

ובעוד זה עובד זהה עבור שניהם javax.inject.Singleton אוֹ javax.ejb סינגלטון, יש הבדל מרכזי בין שני אלה.

4. EJB סינגלטון

כדי ליצור יחידת EJB אנו משתמשים ב- @קְלָף בּוֹדֵד ביאור מה- javax.ejb חֲבִילָה. בדרך זו אנו יוצרים שעועית מושב של סינגלטון.

אנו יכולים לבדוק את ההטמעה באותה הדרך בה בדקנו את הטמעת ה- CDI בדוגמה הקודמת, והתוצאה תהיה זהה. יחידים של EJB, כצפוי, מספקים את המופע היחיד של הכיתה.

למרות זאת, EJB Singletons מספקים גם פונקציונליות נוספת בצורה של בקרת מקבילות המנוהלת על ידי מכיל.

כאשר אנו משתמשים בסוג זה של יישום, מיכל EJB מבטיח כי כל שיטה ציבורית של המחלקה ניגשת באמצעות שרשור אחד בכל פעם. אם מספר שרשורים מנסים לגשת לאותה שיטה, רק שרשור אחד יכול להשתמש בה בזמן שאחרים ממתינים לתורם.

אנו יכולים לאמת התנהגות זו באמצעות בדיקה פשוטה. נציג סימולציה של תור שירות לשיעורי הסינגלטון שלנו:

שירות פרטי סטטי פרטיQueue; שירות ציבורי (רכב רכב) {serviceQueue ++; Thread.sleep (100); car.setServiced (נכון); serviceQueue--; שירות החזרהQueue; } 

serviceQueue מיושם כמספר שלם סטטי רגיל אשר גדל כאשר מכונית "נכנסת" לשירות ופוחתת כאשר היא "עוזבת". אם מספקת נעילה נכונה על ידי המכולה, משתנה זה צריך להיות שווה לאפס לפני השירות ואחריו, ושווה לאחד במהלך השירות.

אנו יכולים לבדוק התנהגות זו באמצעות מבחן פשוט:

@ מבחן ציבורי בטל כאשרEb_thenLockingIsProvided () {for (int i = 0; i <10; i ++) {Thread new (new Runnable () {@Override public void run () {int serviceQueue = carServiceEjbSingleton.service (מכונית חדשה ("Speedster xyz ")); assertEquals (0, serviceQueue);}}). התחל (); } לחזור; } 

בדיקה זו מתחילה 10 שרשורים מקבילים. כל חוט מייצר מכונית ומנסה לשרת אותה. לאחר השירות, הוא קובע כי ערך ה- serviceQueue חוזר לאפס.

אם, למשל, נבצע בדיקה דומה בסינגלטון CDI, הבדיקה שלנו תיכשל.

5. מסקנה

במאמר זה עברנו שני סוגים של יישומים יחידים הזמינים בג'קרטה EE. ראינו את היתרונות והחסרונות שלהם והראינו גם כיצד ומתי להשתמש בכל אחד מהם.

וכמו תמיד, קוד המקור השלם זמין ב- GitHub.


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