גוגל גויס היא הגרסה החדשה של התשתיות של גוגל המיועדת להפעלת הזנת תלות באופן אוטומטי ביישומים. אם הגעתם לכאן ישירות, אני ממליץ לכם לבדוק את דוגמת הזריקת תלות בה אנו למדנו על בעיות הגישה המסורתית של יצירת אובייקט ועל יתרונותיו של הזרקת תלות. בשיעור האחרון, למדנו כיצד ניתן ליישם הזרקת תלות ביישומים באופן ידני. אך כאשר מספר המחלקות גדל ביישום, כדאי לחפש מסגרת שתאפשר לנו לאוטומט את המשימה הזו.
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>3.0</version>
</dependency>
אם יש לך אפליקציה פשוטה ב-Java, אז ניתן להוריד את קובץ ה-JAR מ-דף הבית של גוגל גויס בקוד של גוגל. שים לב שבמקרה זה תצטרך גם להכליל את התלות המשתנות שלו ב-Classpath אחרת יש לך עיתון בזמן הריצה. עבור הדוגמה שלי, יש לי פרויקט Maven שמבנה הפרויקט שלו נראה כמו בתמונה למטה. בואו נסתכל על כל אחד מהרכיבים בנפרד.
סוגי שירות
package com.journaldev.di.services;
public interface MessageService {
boolean sendMessage(String msg, String receipient);
}
MessageService
מספק את הקריאה הבסיסית לשירותים.
package com.journaldev.di.services;
import javax.inject.Singleton;
//import com.google.inject.Singleton;
@Singleton
public class EmailService implements MessageService {
public boolean sendMessage(String msg, String receipient) {
//some fancy code to send email
System.out.println("Email Message sent to "+receipient+" with message="+msg);
return true;
}
}
EmailService
הוא אחד מהמימושים של MessageService
. שימו לב שהמחלקה סומנה עם הערת @Singleton. מאחר ואובייקטי השירות ייווצרו דרך מחלקות האינג'קטור, ניתנה הערה זו כדי להודיע להם שסוגי השירות צריכים להיות אובייקטים יחידים. Google Guice 3.0 הוסיף תמיכה ב-JSR-330 ואנו יכולים להשתמש בהערות מהחבילות com.google.inject
או javax.inject
. נניח שיש לנו גם מימוש נוסף של שירות לשליחת הודעות בפייסבוק.
package com.journaldev.di.services;
import javax.inject.Singleton;
//import com.google.inject.Singleton;
@Singleton
public class FacebookService implements MessageService {
public boolean sendMessage(String msg, String receipient) {
//some complex code to send Facebook message
System.out.println("Message sent to Facebook user "+receipient+" with message="+msg);
return true;
}
}
מחלקת צרכן
מאחר שאנו מיישמים החלפת תלות ביישומונו, לא נאתחל את מחלקת השירות ביישום. Google Guice תומך בכל מניות ההתחלה הבנויות והמתבססות על קונסטרקטור. מחלקת היישום שלנו שמייצגת את השירות נראית כמו למטה.
package com.journaldev.di.consumer;
import javax.inject.Inject;
//import com.google.inject.Inject;
import com.journaldev.di.services.MessageService;
public class MyApplication {
private MessageService service;
// בסיס הכנסת בנאי
// @Inject
// public MyApplication(MessageService svc){
// this.service=svc;
// }
// בנאי על ידי שימוש בקבוע
@Inject
public void setService(MessageService svc){
this.service=svc;
}
public boolean sendMessage(String msg, String rec){
// עסקאות עסקיות כאן
return service.sendMessage(msg, rec);
}
}
שים לב שהערך אותו ציינתי עבור הכנסת בנאי מבוטל, זה מועיל כאשר היישום שלך מספק גם תכונות אחרות שאינן דורשות אובייקט של מחלקת השירות. גם שים לב להערה @Injector זה ישמש את Google Guice להזרקת מחלקת היישום של השירות. אם אינך מודע להערות, תבדוק את המדריך להערות ה-Java java annotations tutorial.
קישור למימוש שירות
ברור כי Google Guice לא יודע לאיזו שירות להשתמש, עלינו להגדיר אותו על ידי הרחבת AbstractModule
כיתה מופשטת ולספק מימוש לשיטה configure()
.
package com.journaldev.di.injector;
import com.google.inject.AbstractModule;
import com.journaldev.di.services.EmailService;
import com.journaldev.di.services.FacebookService;
import com.journaldev.di.services.MessageService;
public class AppInjector extends AbstractModule {
@Override
protected void configure() {
// חייב את השירות למימוש הכיתה
//bind(MessageService.class).to(EmailService.class);
// חביר את MessageService למימוש ההודעה בפייסבוק
bind(MessageService.class).to(FacebookService.class);
}
}
כפי שאתה רואה, אנו יכולים לקשור כל מימוש למחלקת שירות. לדוגמה, אם נרצה לשנות ל-EmailService, יהיה עלינו רק לשנות את הקישורים.
יישום לקוח
ההגדרה שלנו מוכנה, בואו נראה איך להשתמש בה עם כיתה פשוטה ב-Java.
package com.journaldev.di.test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.journaldev.di.consumer.MyApplication;
import com.journaldev.di.injector.AppInjector;
public class ClientApplication {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AppInjector());
MyApplication app = injector.getInstance(MyApplication.class);
app.sendMessage("Hi Pankaj", "[email protected]");
}
}
המימוש קל להבנה. אנו צריכים ליצור אובייקט Injector
באמצעות המתודה createInjector() של מחלקת Guice, שבה נעביר אובייקט המימוש של מחלקת ה-Injector שלנו. לאחר מכן, אנו משתמשים ב-Injector כדי לאתחל את מחלקת הצרכן שלנו. אם נפעיל את הכיתה לעיל, היא תפיק פלט הבא.
Message sent to Facebook user [email protected] with message=Hi Pankaj
אם נשנה את הקישורים ל-EmailService
במחלקת AppInjector
, זה יפיק את הפלט הבא.
Email Message sent to [email protected] with message=Hi Pankaj
מבחני יחידה JUnit
מאחר שאנו רוצים לבדוק את המחלקה MyApplication, לא יהיה עלינו ליצור יישום אמיתי של השירות. נוכל להשתמש במימוש פשוט של מחלקת השירות המקובלת, כמו שמוצג למטה.
package com.journaldev.di.services;
public class MockMessageService implements MessageService{
public boolean sendMessage(String msg, String receipient) {
return true;
}
}
המחלקה שלי לבדיקות JUnit 4 נראית כך.
package com.journaldev.di.test;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.journaldev.di.consumer.MyApplication;
import com.journaldev.di.services.MessageService;
import com.journaldev.di.services.MockMessageService;
public class MyApplicationTest {
private Injector injector;
@Before
public void setUp() throws Exception {
injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(MessageService.class).to(MockMessageService.class);
}
});
}
@After
public void tearDown() throws Exception {
injector = null;
}
@Test
public void test() {
MyApplication appTest = injector.getInstance(MyApplication.class);
Assert.assertEquals(true, appTest.sendMessage("Hi Pankaj", "[email protected]"));;
}
}
שים לב שאני קושר את מחלקת MockMessageService
למחלקת MessageService
על ידי ביצוע יישום של מחלקה אנונימית של AbstractModule
. זה נעשה בשיטה setUp()
שרצה לפני שיטות הבדיקה.
זהו כל המדר המקיף על דוגמא של Google Guice. שימוש ב-Google Guice ליישום זרימת תלות באפליקציה הוא קל מאוד והוא עושה זאת בצורה יפה. הספרייה נמצאת בשימוש ב-API של Google, כך שאפשר להניח שזו קוד מאוד נבדק ואמין. הורד את הפרויקט מהלינק למעלה ושחק עם זה כדי ללמוד עוד.
Source:
https://www.digitalocean.com/community/tutorials/google-guice-dependency-injection-example-tutorial