Google Guice 종속성 주입 예제 튜토리얼

Google Guice는 응용 프로그램에서 종속성 주입을 자동화하는 프레임워크입니다. 여기에 직접 왔다면, 의존성 주입 예제를 확인하는 것이 좋습니다. 거기서 우리는 객체 생성의 전통적인 접근 방식의 문제와 종속성 주입의 구현 이점을 배웠습니다. 마지막 튜토리얼에서는 응용 프로그램에서 종속성 주입을 수동으로 어떻게 구현할 수 있는지 배웠습니다. 그러나 응용 프로그램의 클래스 수가 증가하면 이 작업을 자동화하는 어떤 프레임워크를 찾는 것이 좋습니다. Google Guice는 주요 작업이 종속성 주입의 자동 구현을 제공하는 주요 프레임워크 중 하나입니다. 지난 게시물에서와 같은 예제에서 작업하고 Google Guice를 사용하여 종속성 주입의 구현 프로세스를 자동화하는 방법을 배워보겠습니다. Google Guice 종속성은 메이븐 중앙에 제공되므로 메이븐 프로젝트의 경우 아래 종속성을 추가할 수 있습니다.

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

간단한 자바 애플리케이션이 있다면 Google Code의 Google Guice 홈페이지에서 jar 파일을 다운로드할 수 있습니다. 이 경우에도 클래스패스에 이에 대한 전이적 종속성이 있어야 하며 그렇지 않으면 런타임 예외가 발생합니다. 내 예제에서는 프로젝트 구조가 아래 이미지와 같은 메이븐 프로젝트가 있습니다. 각 구성 요소를 하나씩 살펴보겠습니다.

서비스 클래스

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.inject 또는 javax.inject 패키지의 주석을 사용할 수 있습니다. 페이스북 메시지를 보내는 또 다른 서비스 구현이 있다고 가정해 봅시다.

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) {
		//페이스북 메시지를 보내는 복잡한 코드
		System.out.println("Message sent to Facebook user "+receipient+" with message="+msg);
		return true;
	}

}

소비자 클래스

의존성 주입을 구현 중이므로 애플리케이션에서 서비스 클래스를 초기화하지 않습니다. Google Guice는 setter 기반생성자 기반 의존성 주입을 모두 지원합니다. 서비스를 사용하는 애플리케이션 클래스는 아래와 같습니다.

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;
	
// 생성자 기반 주입
// @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에서 서비스 구현 클래스를 주입하는 데 사용됩니다. 주석에 익숙하지 않은 경우 자바 주석 튜토리얼을(를) 확인하십시오.

서비스 구현 바인딩

명백하게 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로 변경하려면 바인딩만 변경하면 됩니다.

클라이언트 응용 프로그램

우리의 설정이 준비되었습니다. 간단한 자바 클래스와 함께 사용하는 방법을 살펴 봅시다.

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 클래스를 테스트하려면 실제 서비스 구현을 생성할 필요가 없습니다. 아래와 같이 간단한 Mock 서비스 구현 클래스를 가질 수 있습니다.

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

}

알림 : 나는 MockMessageService 클래스를 MessageService에 바인딩하는 것을 AbstractModule의 익명 클래스 구현을 통해 수행합니다. 이것은 테스트 메서드 전에 실행되는 setUp() 메서드에서 수행됩니다.

Google Guice 프로젝트 다운로드

Google Guice 예제 튜토리얼은 여기까지입니다. 애플리케이션에서 의존성 주입을 구현하기 위해 Google Guice를 사용하는 것은 매우 쉽고 아름답게 처리됩니다. Google API에서 사용되므로 고도로 테스트되고 신뢰할 수 있는 코드라고 가정할 수 있습니다. 위의 링크에서 프로젝트를 다운로드하여 더 많이 배우세요.

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