Рубрики
Без рубрики

Пример руководства по внедрению зависимостей Google Guice

Пример учебника Google Guice. Инъекция зависимостей Google Guice, Guice @Inject, @Singleton, Пример инжектора Guice, Guice.createInjector, getInstance

Автор оригинала: Pankaj Kumar.

Google Guice – это платформа для автоматизации внедрения зависимостей в приложения. Если вы столкнулись непосредственно здесь, я бы рекомендовал вам проверить Пример внедрения зависимостей , где мы узнали о проблемах с традиционным подходом к созданию объектов и преимуществах внедрения зависимостей.

В последнем уроке мы узнали, как можно внедрить внедрение зависимостей в приложения вручную. Но когда количество классов в приложении растет, лучше поискать какой-нибудь фреймворк для автоматизации этой задачи.

Google Guice-одна из ведущих платформ, основная работа которой заключается в обеспечении автоматической реализации внедрения зависимостей. Мы рассмотрим тот же пример из предыдущего поста и узнаем, как мы можем использовать Google Guice для автоматизации процесса внедрения внедрения зависимостей.

Зависимости Google Guice доступны в maven central, поэтому для проектов maven вы можете добавить для него зависимость ниже.


	com.google.inject
	guice
	3.0

Если у вас есть простое java-приложение, вы можете загрузить файл jar с домашней страницы Google Guice в Google Code. Обратите внимание, что в этом случае вам также потребуется указать переходные зависимости в пути к классу, иначе вы получите исключение во время выполнения.

Для моего примера у меня есть проект maven, структура проекта которого выглядит следующим образом.

Давайте рассмотрим каждый из компонентов по очереди.

Классы обслуживания

package com.journaldev.di.services;

public interface MessageService {

	boolean sendMessage(String msg, String receipient);
}

Служба сообщений интерфейс предоставляет базовый контракт на услуги.

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

}

Служба электронной почты является одной из реализаций Службы сообщений . Обратите внимание, что класс аннотирован аннотацией @Singleton. Поскольку объекты обслуживания будут создаваться с помощью классов инжекторов, эта аннотация предназначена для того, чтобы они знали, что классы обслуживания должны быть одноэлементными объектами.

Google Guice 3.0 добавил поддержку JSR-330, и мы можем использовать аннотации из com.google.inject или javax.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) {
		//some complex code to send Facebook message
		System.out.println("Message sent to Facebook user "+receipient+" with message="+msg);
		return true;
	}

}

Класс потребителей

Поскольку мы внедряем внедрение зависимостей в наше приложение, мы не будем инициализировать класс обслуживания в приложении. Google Guice поддерживает как на основе установщика , так и на основе конструктора внедрение зависимостей. Наш класс приложений, использующий сервис, выглядит следующим образом.

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 the service to implementation class
		//bind(MessageService.class).to(EmailService.class);
		
		//bind MessageService to Facebook Message implementation
		bind(MessageService.class).to(FacebookService.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");
	}

}

Реализация очень проста для понимания. Нам нужно создать Инжектор объект, использующий метод класса Guice createInjector (), в котором мы передаем наш объект реализации класса инжектора. Затем мы используем инжектор для инициализации нашего потребительского класса. Если мы запустим выше класса, он выдаст следующий результат.

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

Если мы изменим привязки к Почтовой службе в Инжекторе приложений классе, то он выдаст следующий вывод.

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

Тестовые случаи JUnit

Поскольку мы хотим протестировать мой класс приложений, нам не требуется создавать фактическую реализацию службы. У нас может быть простой класс реализации макетной службы, как показано ниже.

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

}

Обратите внимание, что я привязываю MockMessageService класс к Службе сообщений , используя анонимный класс реализацию Абстрактного модуля . Это делается в методе setUp () , который выполняется перед методами тестирования.

Это все для примера учебника Google Guice. Использование Google Guice для внедрения внедрения зависимостей в приложение очень просто и делает это красиво. Он используется в API Google, поэтому мы можем предположить, что это хорошо протестированный и надежный код. Загрузите проект сверху и поиграйте с ним, чтобы узнать больше.