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中,因此我们可以认为它经过了高度测试,并且是可靠的代码。从上面下载该项目并进行尝试,以了解更多。