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.Olivia.di.services;

public interface MessageService {

	boolean sendMessage(String msg, String receipient);
}

MessageService 接口为服务提供基础合约。

package com.Olivia.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包中的注释。假设我们还有另一个服务实现来发送Facebook消息。

package com.Olivia.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支持基于setter和构造函数的依赖注入两种方式。我们消耗服务的应用程序类如下所示。

package com.Olivia.di.consumer;

import javax.inject.Inject;

//import com.google.inject.Inject;
import com.Olivia.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注解教程。

服务绑定的实施

明显地,谷歌Guice并不知道要使用哪个服务,我们必须通过扩展AbstractModule抽象类并为configure()方法提供实现来进行配置。

package com.Olivia.di.injector;

import com.google.inject.AbstractModule;
import com.Olivia.di.services.EmailService;
import com.Olivia.di.services.FacebookService;
import com.Olivia.di.services.MessageService;

public class AppInjector extends AbstractModule {

	@Override
	protected void configure() {
		//bind the service to implementation class
		//bind(MessageService.class).to(EmailService.class);
		
		//bind MessageService to Facebook Message implementation
		bind(MessageService.class).to(FacebookService.class);
		
	}

}

正如您所见,我们可以将任何实现绑定到服务类。例如,如果我们想要更改为EmailService,只需改变绑定即可。

客户端应用程序

我们的设置已经准备好了,让我们看看如何在一个简单的Java类中使用它。

package com.Olivia.di.test;

import com.google.inject.Guice;
import com.google.inject.Injector;

import com.Olivia.di.consumer.MyApplication;
import com.Olivia.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", "scdev@abc.com");
	}

}

实现非常容易理解。我们需要使用Guice类的createInjector()方法创建Injector对象,其中我们传入我们的实现了injector类的对象。然后我们使用injector来初始化我们的consumer类。如果我们运行上述类,它将产生以下输出。

Message sent to Facebook user scdev@abc.com with message=Hi Pankaj

如果我们在AppInjector类中更改对EmailService的绑定,那么将产生以下输出结果。

Email Message sent to scdev@abc.com with message=Hi Pankaj

JUnit测试用例

因为我们想要测试MyApplication类,所以我们不需要创建实际的服务实现。我们可以有一个简单的模拟服务实现类,如下所示。

package com.Olivia.di.services;

public class MockMessageService implements MessageService{

	public boolean sendMessage(String msg, String receipient) {
		return true;
	}

}

我的JUnit 4测试类如下所示。

package com.Olivia.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.Olivia.di.consumer.MyApplication;
import com.Olivia.di.services.MessageService;
import com.Olivia.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", "scdev@abc.com"));;
	}

}

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

下载谷歌Guice项目

对于Google Guice示例教程就介绍到这里。在应用中使用Google Guice实现依赖注入非常简单且有效。它被用于Google的API中,因此我们可以认为它经过了高度测试,并且是可靠的代码。从上面下载该项目并进行尝试,以了解更多。

发表回复 0

Your email address will not be published. Required fields are marked *