guice依赖注入原理_Google Guice依赖注入示例教程

guice依赖注入原理

Google Guice is the framework to automate the dependency injection in applications. If you have come across directly here, I would recommend you to check out Dependency Injection Example where we learned the problems with traditional approach of Object creation and implementation benefits of dependency injection.

Google Guice是在应用程序中自动进行依赖项注入的框架。 如果您直接在这里遇到过,我建议您查看“ 依赖注入示例” ,在该示例中我们了解了传统对象创建方法的问题以及依赖注入的实现好处。

In last tutorial, we learned how can we implement dependency injection in applications manually. But when number of classes grow in an application, it’s better to look for some framework to automate this task.

在上一教程中,我们学习了如何在应用程序中手动实现依赖项注入。 但是,当应用程序中的类数量增加时,最好寻找一些框架来自动执行此任务。

Google Guice is one of the leading frameworks whose main work is to provide automatic implementation of dependency injection. We will work on the same example from last post and learn how can we use Google Guice to automate the implementation process for dependency injection.

Google Guice是主要的框架之一,其主要工作是提供依赖关系注入的自动实现。 我们将与上一篇文章中的相同示例一起工作,并学习如何使用Google Guice自动执行依赖项注入的实现过程。

Google Guice dependencies are available on maven central, so for maven projects you can add below dependency for it.

Google Guice依赖项在Maven Central上可用,因此对于Maven项目,您可以为其添加以下依赖项。

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

If you have a simple java application, then you can download the jar file from Google Guice Home Page on Google Code. Note that in this case you will also need to have it’s transitive dependencies in the classpath or else you will get runtime exception.

如果您有一个简单的Java应用程序,则可以从Google Code上的Google Guice主页下载jar文件。 请注意,在这种情况下,您还需要在类路径中具有传递依赖项,否则将获得运行时异常。

For my example, I have a maven project whose project structure looks like below image.

对于我的示例,我有一个Maven项目,其项目结构如下图所示。

Let’s see each of the components one by one.

让我们一个一个地查看每个组件。

服务等级 (Service Classes)

package com.journaldev.di.services;

public interface MessageService {

	boolean sendMessage(String msg, String receipient);
}

MessageService interface provides the base contract for the services.

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) {
		//some fancy code to send email
		System.out.println("Email Message sent to "+receipient+" with message="+msg);
		return true;
	}

}

EmailService is one of the implementation of MessageService. Notice that class is annotated with @Singleton annotation. Since service objects will be created through injector classes, this annotation is provided to let them know that the service classes should be singleton objects.

EmailServiceMessageService的实现之一。 注意,该类使用@Singleton注释进行了注释。 由于将通过注入器类创建服务对象,因此提供此批注以使他们知道服务类应为单例对象。

Google Guice 3.0 added the support for JSR-330 and we can use annotations from com.google.inject or javax.inject package.

Google Guice 3.0添加了对JSR-330的支持,我们可以使用com.google.injectjavax.inject包中的注释。

Let’s say we have another service implementation to send facebook messages.

假设我们有另一个服务实现来发送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) {
		//some complex code to send Facebook message
		System.out.println("Message sent to Facebook user "+receipient+" with message="+msg);
		return true;
	}

}

消费阶层 (Consumer Class)

Since we are implementing dependency injection in our application, we won’t initialize the service class in application. Google Guice support both setter-based and constructor-based dependency injection. Our application class that consumes the service looks like below.

由于我们在应用程序中实现依赖项注入,因此我们不会在应用程序中初始化服务类。 Google Guice支持setter-based constructor-based依赖项注入。 我们使用该服务的应用程序类如下所示。

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

Notice that I have commented the code for constructor based injection, this comes handy when your application provides some other features too that doesn’t need service class object.

请注意,我已经注释了基于构造函数的注入的代码,当您的应用程序也提供不需要服务类对象的其他功能时,这将很方便。

Also notice the @Injector annotation, this will be used by Google Guice to inject the service implementation class. If you are not familiar with annotations, check out java annotations tutorial.

还要注意@Injector批注,Google Guice将使用它来注入服务实现类。 如果您不熟悉注释,请查看Java注释教程

绑定服务实现 (Binding Service implementation)

Obviously google guice will not know which service to use, we have to configure it by extending AbstractModule abstract class and provide implementation for configure() method.

显然,谷歌guice不会知道要使用哪个服务,我们必须通过扩展AbstractModule 抽象类对其进行configure()并为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 the service to implementation class
		//bind(MessageService.class).to(EmailService.class);
		
		//bind MessageService to Facebook Message implementation
		bind(MessageService.class).to(FacebookService.class);
		
	}

}

As you can see that we can bind any of the implementation to service class. For example, if we want to change to EmailService we would just need to change the bindings.

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

客户申请 (Client Application)

Our setup is ready, let’s see how to use it with a simple java class.

我们的设置已经准备就绪,让我们看看如何在简单的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", "pankaj@abc.com");
	}

}

The implementation is very easy to understand. We need to create Injector object using Guice class createInjector() method where we pass our injector class implementation object. Then we use injector to initialize our consumer class. If we run above class, it will produce following output.

实现非常容易理解。 我们需要使用Guice类的createInjector()方法创建Injector对象,并在其中传递我们的注射器类实现对象。 然后,我们使用注入器初始化我们的消费者类。 如果我们在类上运行,它将产生以下输出。

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

If we change the bindings to EmailService in AppInjector class then it will produce following output.

如果我们更改AppInjector类中对EmailService的绑定,则它将产生以下输出。

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

JUnit测试用例 (JUnit Test Cases)

Since we want to test MyApplication class, we are not required to create actual service implementation. We can have a simple Mock service implementation class like below.

由于我们要测试MyApplication类,因此不需要创建实际的服务实现。 我们可以有一个简单的Mock服务实现类,如下所示。

package com.journaldev.di.services;

public class MockMessageService implements MessageService{

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

}

My JUnit 4 test class looks like below.

我的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", "pankaj@abc.com"));;
	}

}

Notice that I am binding MockMessageService class to MessageService by having an anonymous class implementation of AbstractModule. This is done in setUp() method that runs before the test methods.

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

That’s all for Google Guice Example Tutorial. Use of Google Guice for implementing dependency injection in application is very easy and it does it beautifully. It’s used in Google APIs so we can assume that it’s highly tested and reliable code. Download the project from above and play around with it to learn more.

这就是Google Guice示例教程的全部内容。 使用Google Guice在应用程序中实施依赖项注入非常容易,而且效果非常好。 它在Google API中使用,因此我们可以假定它是经过高度测试和可靠的代码。 从上方下载项目并进行试用以了解更多信息。

翻译自: https://www.journaldev.com/2403/google-guice-dependency-injection-example-tutorial

guice依赖注入原理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值