Google Guice 是一個用於自動化應用程式中的依賴注入的框架。如果你直接到這裡,我建議你查看依賴注入範例,在那裡我們學習了傳統對象創建方法的問題,以及依賴注入的實現好處。在上一個教程中,我們學習了如何手動實現依賴注入。但是當應用程序中的類數量增加時,最好尋找一些框架來自動執行此任務。Google Guice是其中一個主要框架,其主要工作是提供依賴注入的自動實現。我們將使用上一篇文章中的相同示例,並學習如何使用Google Guice來自動執行依賴注入的實現過程。Google Guice的依賴項可以在maven中央庫中找到,因此對於maven項目,您可以添加以下依賴項。
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>3.0</version>
</dependency>
如果您有一個簡單的Java應用程序,那麼您可以從Google Guice首頁在Google Code上下載jar文件。請注意,在這種情況下,您還需要將其遞歸依賴項添加到類路徑中,否則您將收到運行時異常。對於我的示例,我有一個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) {
//一些很酷的程式碼來發送郵件
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
套件中的標註。假設我們還有另一個用於發送Facebook消息的服務實作。
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) {
//一些複雜的程式碼來發送Facebook消息
System.out.println("Message sent to Facebook user "+receipient+" with message="+msg);
return true;
}
}
消費者類別
由於我們正在應用程式中實作依賴注入,我們不會在應用程式中初始化服務類別。Google Guice支援基於setter
和constructor
的依賴注入。我們的應用程式類別,用於消耗此服務,如下所示。
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;
// constructor based injector
// @Inject
// public MyApplication(MessageService svc){
// this.service=svc;
// }
//setter method injector
@Inject
public void setService(MessageService svc){
this.service=svc;
}
public boolean sendMessage(String msg, String rec){
//some business logic here
return service.sendMessage(msg, rec);
}
}
注意到我已經為基於構造函數的注入部分的代碼進行了注釋,當您的應用程序還提供了一些不需要服務類對象的其他功能時,這很方便。還要注意@Injector注釋,這將由Google Guice用於注入服務實現類。如果您對註釋不熟悉,請查看Java註釋教程。
綁定服務實現
顯然,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綁定到Facebook Message實現
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]");
}
}
實現非常容易理解。我們需要使用Guice類的createInjector()方法創建`Injector`對象,在其中傳遞我們的`injector`類實現對象。然後,我們使用`injector`來初始化我們的消費者類。如果我們運行上面的類,它將生成以下輸出。
Message sent to Facebook user [email protected] with message=Hi Pankaj
如果我們在`AppInjector`類中將綁定更改為`EmailService`,則它將生成以下輸出。
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 進行依賴注入非常簡單,而且它的實現非常優雅。它被用於 Google APIs 中,因此我們可以假設它的代碼經過了高度測試且可靠。從上面下載該專案並且開始實驗,以便更多地了解。
Source:
https://www.digitalocean.com/community/tutorials/google-guice-dependency-injection-example-tutorial