Google Guice 依賴注入範例教程

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;
	}

}

EmailServiceMessageService的一個實作。請注意,該類別被標註為@Singleton。由於服務物件將通過注入器類別創建,此標註用於告訴它們服務類別應該是單例物件。Google Guice 3.0新增了對JSR-330的支援,我們可以使用com.google.injectjavax.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支援基於setterconstructor的依賴注入。我們的應用程式類別,用於消耗此服務,如下所示。

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 Guice 進行依賴注入非常簡單,而且它的實現非常優雅。它被用於 Google APIs 中,因此我們可以假設它的代碼經過了高度測試且可靠。從上面下載該專案並且開始實驗,以便更多地了解。

Source:
https://www.digitalocean.com/community/tutorials/google-guice-dependency-injection-example-tutorial