Google Guice 依赖注入示例教程

谷歌Guice是用于自动化应用程序中的依赖注入的框架。如果你直接来到这里,我建议你查看《依赖注入示例》,在那里我们了解了传统对象创建方法的问题以及依赖注入的实现优势。在上一个教程中,我们学习了如何手动实现应用程序中的依赖注入。但是当应用程序中的类数量增加时,最好寻找一些框架来自动化此任务。谷歌Guice是主要提供依赖注入自动实现的主要框架之一。我们将从上一篇文章中的相同示例开始,学习如何使用谷歌Guice来自动执行依赖注入的实现过程。谷歌Guice的依赖关系可以在maven中央仓库中找到,因此对于maven项目,您可以添加以下依赖项。

<dependency>
	<groupId>com.google.inject</groupId>
	<artifactId>guice</artifactId>
	<version>3.0</version>
</dependency>

如果您有一个简单的Java应用程序,那么您可以从谷歌代码的谷歌Guice主页上下载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;

//导入 com.google.inject.Inject;
import com.journaldev.di.services.MessageService;

public class MyApplication {

	private MessageService service;
	
//基于构造函数的注入
//	@Inject
//public MyApplication(MessageService svc){
//		this.service=svc;
//	}
	
	//基于setter方法的注入
	@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 注释教程

绑定服务实现

显然,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对象,其中我们传递我们的注射器类实现对象。然后,我们使用注射器初始化我们的消费者类。如果我们运行上述类,它将产生以下输出。

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]"));;
	}

}

注意我通过使用AbstractModule匿名类实现,将MockMessageService类绑定到MessageService。这是在运行测试方法之前的setUp()方法中完成的。

下载 Google Guice 项目

以上就是 Google Guice 示例教程的全部内容。在应用程序中实现依赖注入的 Google Guice 的使用非常简单,而且它执行得非常好。它被用于 Google API 中,因此我们可以假设它经过了高度测试并且是可靠的代码。从上面下载项目并进行更多实践来学习更多。

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