מדריך ל- Google Guice

1. הקדמה

מאמר זה יבחן היסודות של Google Guice. נבחן גישות להשלמת משימות בסיסיות של הזרקת תלות (DI) ב- Guice.

אנו נשווה ונשווה בין גישת Guice לאלו של מסגרות DI מבוססות יותר כמו Spring and Contexts and Dependency Injection (CDI).

מאמר זה מניח שהקורא מבין את יסודות דפוס הזרקת התלות.

2. התקנה

על מנת להשתמש ב- Google Guice בפרויקט Maven שלך, יהיה עליך להוסיף את התלות הבאה שלך pom.xml:

 com.google.inject guice 4.1.0 

יש כאן גם אוסף של סיומות של Guice (נסקור אותן מעט מאוחר יותר), כמו גם מודולים של צד שלישי להרחבת היכולות של Guice (בעיקר על ידי מתן שילוב למסגרות Java מבוססות יותר).

3. הזרקת תלות בסיסית עם מדריך

3.1. היישום לדוגמא שלנו

נעבוד עם תרחיש בו אנו מעצבים שיעורים התומכים בשלושה אמצעי תקשורת בעסק של דלפק העזרה: דוא"ל, SMS ו- IM.

שקול את הכיתה:

תקשורת בכיתה ציבורית {@ הזרק לוגר לוגר פרטי; @ הזריק מתקשר תקשורת פרטי; תקשורת ציבורית (Boolean keepRecords) {if (keepRecords) {System.out.println ("רישום הודעות מופעל"); }} sendMessage בוליאני ציבורי (הודעת מחרוזת) {return communicator.sendMessage (הודעה); }}

זֶה תִקשׁוֹרֶת הכיתה היא יחידת התקשורת הבסיסית. מופע של מחלקה זו משמש לשליחת הודעות בערוצי התקשורת הזמינים. כפי שמוצג לעיל, תִקשׁוֹרֶת יש מתקשר בה אנו משתמשים כדי להעביר את ההודעה בפועל.

נקודת הכניסה הבסיסית לגויס היא מַזרֵק:

main main static public (String [] args) {Injector injector = Guice.createInjector (חדש BasicModule ()); Comms comms = injector.getInstance (תקשורת.קלאס); } 

שיטה עיקרית זו מאחזרת מופע משלנו תִקשׁוֹרֶת מעמד. זה גם מציג מושג בסיסי של Guice: מודול (באמצעות BasicModule בדוגמה זו). ה מודול היא יחידת ההגדרה הבסיסית של כריכות (או חיווט, כידוע באביב).

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

בדוגמה לעיל, עץ התלות של תִקשׁוֹרֶת יוזרק במרומז באמצעות תכונה הנקראת מחייב בדיוק בזמן, בתנאי שלשיעורים יש את בנאי ברירת המחדל ללא ארגון. זו הייתה תכונה ב- Guice מאז הקמתה וזמינה רק באביב מאז v4.3.

3.2. קשירת גויסות

הכריכה היא לגויס כמו החיווט לאביב. עם כריכות, אתה להגדיר כיצד Guice הולך להזריק תלות לכיתה.

כריכה מוגדרת ביישום של com.google.inject.AbstractModule:

מחלקה ציבורית BasicModule מרחיב את AbstractModule {@Override מוגן חלל להגדיר () {bind (Communicator.class) .to (DefaultCommunicatorImpl.class); }}

יישום מודול זה מציין כי מופע של בְּרִירַת מֶחדָלCommunicatorImpl יש להזריק בכל מקום בו מתקשר משתנה נמצא.

גלגול נוסף של מנגנון זה הוא ה- נקשר מחייב. שקול את ההצהרה המשתנה הבאה:

@Inject @Named ("תקשורת ברירת מחדל") מתקשר תקשורת; 

לשם כך תהיה לנו ההגדרה המחייבת הבאה:

תצורת הריק מוגנת @Override () {bind (Communicator.class) .annotatedWith (Names.named ("DefaultCommunicator")) .to (Communicator.class); } 

כריכה זו תספק מופע של מתקשר למשתנה המסומן עם ה- @Named ("ברירת מחדל תקשורת") ביאור.

תבחין ב @לְהַזרִיק ו @ שמות נראה כי ביאורים הם הערות הלוואות מה- CDI של ג'קרטה אי.איי. הם ב com.google.inject. * חבילה - עליכם להקפיד לייבא מהחבילה הנכונה בעת שימוש ב- IDE.

עֵצָה: אמנם רק אמרנו להשתמש במתן Guice @לְהַזרִיק ו @ שמותכדאי לציין שגויס אכן מספק תמיכה ב javax.inject.Inject ו javax.inject. שם, בין שאר ההערות של ג'קרטה EE.

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

מחלקה ציבורית BasicModule מרחיב את AbstractModule {@Override מוגן ריק configure () {bind (Boolean.class) .toInstance (true); לאגד (Communication.class). toConstructor (Communication.class.getConstructor (Boolean.TYPE)); } 

קטע הקוד לעיל יזריק מופע של תִקשׁוֹרֶת באמצעות הבנאי שלוקח א בוליאני טַעֲנָה. אנו מספקים את נָכוֹן ויכוח לבנאי מאת הגדרת כריכה לא ממוקדת של ה בוליאני מעמד.

זֶה כריכה לא ממוקדת יסופק בשקיקה לכל בנאי בכריכה המקבל א בוליאני פָּרָמֶטֶר. עם גישה זו, כל התלות של תִקשׁוֹרֶת מוזרקים.

גישה נוספת לכריכה ספציפית לבנאי היא ה- כריכת מופע, שם אנו מספקים מופע ישירות בכריכה:

המחלקה הציבורית BasicModule מרחיבה את AbstractModule {@Override מוגן ריק configure () {bind (Communication.class) .toInstance (תקשורת חדשה (true)); }}

כריכה זו תספק מופע של תִקשׁוֹרֶת כיתה בכל מקום א תִקשׁוֹרֶת משתנה מוכרז.

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

4. סוגי הזרקת תלות

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

4.1. הזרקת שדה

@Inject @Named ("SMSComms") תקשורת מצב smsComms;

השתמש באופציה @ שמות ביאור כמסמך ליישום הזרקה ממוקדת על בסיס השם

4.2. הזרקת שיטה

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

@ הזריק את הריק הציבורי setEmailCommunicator (@Named ("EmailComms") CommunicationMode emailComms) {this.emailComms = emailComms; } 

4.3. הזרקת קונסטרוקטור

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

@ הזריק תקשורת ציבורית (@Named ("IMComms") imComms CommunicationMode) {this.imComms = imComms; } 

4.4. זריקות מרומזות

Guice יזריק במרומז כמה רכיבים למטרות כלליות כמו מַזרֵק ומופע של java.util.Logger, בין היתר. תבחין שאנחנו משתמשים בכורתים בכל הדגימות, אך לא תמצא מחייב בפועל עבורם.

5. סקופינג בגויס

Guice תומך בהיקפים ובמנגנוני הסקירה שהתרגלנו אליהם במסגרות DI אחרות. Guice ברירת המחדל היא לספק מופע חדש של תלות מוגדרת.

5.1. קְלָף בּוֹדֵד

בואו נזריק יישום יחיד ליישום שלנו:

לאגד (Communicator.class) .annotatedWith (Names.named ("AnotherCommunicator")) .to (Communicator.class) .in (Scopes.SINGLETON); 

ה ב (Scopes.SINGLETON) מציין כי מתקשר שדה עם @Named ("אחר מתקשר") יקבל יחידן מוזרק. הסינגלון הזה יוזם בעצלתיים כברירת מחדל.

5.2. סינגלטון להוט

עכשיו, בואו נזריק סינגלטון להוט:

לאגד (Communicator.class) .annotatedWith (Names.named ("AnotherCommunicator")) .to (Communicator.class) .asEagerSingleton (); 

ה asEagerSingleton () שיחה מגדירה את הסינגלנט כמייצר בשקיקה.

בנוסף לשני היקפים אלה, Guice תומך בהיקפים מותאמים אישית כמו גם באינטרנט בלבד @ RequestScoped ו @SessionScoped הערות, המסופקות על ידי ג'קרטה EE (אין גרסאות שסופקו על ידי Guice להערות אלה).

6. תכנות מונחה-היבט בגויסה

Guice תואם את המפרט של AOPAlliance לתכנות מונחה-היבט. אנו יכולים ליישם את מיירט הרישום המהותי, שבו נשתמש כדי לעקוב אחר שליחת הודעות בדוגמה שלנו, בארבעה שלבים בלבד.

שלב 1 - יישם את AOPAlliance שיטת מיירט:

מחלקה ציבורית MessageLogger מיישם את MethodInterceptor {@Inject Logger logger; @Override הפעל אובייקט ציבורי (קריאת MethodInvocation) זורק {Object [] objectArray = invocation.getArguments () לזריק; עבור (אובייקט אובייקט: objectArray) {logger.info ("שליחת הודעה:" + object.toString ()); } להחזיר קריאה. להמשיך (); }} 

שלב 2 - הגדר הערת Java רגילה:

@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) ציבורי @interface MessageSentLoggable {} 

שלב 3 - הגדר כריכה עבור התאמה:

שידוך הוא מחלקה של Guice בה אנו משתמשים, אך מציינים את הרכיבים עליהם יחול הערת ה- AOP שלנו. במקרה זה, אנו רוצים שההערה תחול על יישומים של תקשורת מצב:

מחלקה ציבורית AOPModule מרחיב את AbstractModule {@Override מוגן void configure () {bindInterceptor (Matchers.any (), Matchers.annotatedWith (MessageSentLoggable.class), MessageLogger חדש ()); }} 

ציינו א שידוך כאן שיחיל את שלנו MessageLogger מיירט ל כל בכיתה, שיש לה את MessageSentLoggable ביאור מוחל על שיטותיו.

שלב 4 - החל את ההערה שלנו על מצב התקשורת שלנו וטען את המודול שלנו

@Override @MessageSentLogable ציבור בוליאני sendMessage (הודעת מחרוזת) {logger.info ("הודעת SMS נשלחה"); לחזור אמיתי; } ראשי ריק סטטי ציבורי (String [] args) {Injector injector = Guice.createInjector (BasicModule חדש (), AOPModule חדש ()); Comms comms = injector.getInstance (תקשורת.קלאס); }

7. מסקנה

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

לצד התמיכה ב- JSR-330, Guice שואפת להיות מסגרת DI ממוקדת בהזרקה (ואילו Spring מספק מערכת אקולוגית שלמה לנוחות תכנות לא בהכרח רק DI), המיועדת למפתחים שרוצים גמישות DI.

Guice ניתן גם להרחבה ומאפשר למתכנתים לכתוב תוספים ניידים שמביאים לשימושים גמישים ויצירתיים במסגרת. זאת בנוסף לשילוב הנרחב שכבר מספקת Guice למסגרות ולפלטפורמות הפופולריות ביותר כמו Servlets, JSF, JPA ו- OSGi, עד כמה שם.

אתה יכול למצוא את כל קוד המקור המשמש במדריך זה בפרויקט GitHub שלנו.