DI(Dependency Injection)**, **의존성 주입

의존 관계가 소스코드 내부가 아닌 외부로부터 주입되는 것.

<br/>

<br/>

PetOwner클래스가 AnimalType 인터페이스에 의존 관계를 주입할때 다음과 같이 구현하였다.

public class PetOwner {
	AnimalType animal;

	public PetOwner() {
		this.animal = new Cat();
	}
}
<br/>

위 코딩은 결합도가 높은 코딩을 보여준다.

예를들어 Cat이 아닌 Dog로 변경한다면, PetOwner 클래스를 변경해야 할 것이다.

<br/>

우리는 결합도를 낮추고싶다. 그래서 다음과 같이 변경하였다.

public class PetOwner {
	AnimalType animal;

	public PetOwner(AnimalType animalType) {
		this.animal = animalType;
	}
}
<br/>
public class Main {
	public static void main(String[] args) {
		AnimalType animalType = new Cat();
		PetOwner petOwner = new PetOwner(animalType);
	}
}

PetOwner클래스와 AnimalType 인터페이스 간의 결합도는 낮추는 것에 성공하였다.

Cat을 Dog로 바꾸더라도, PetOwner 클래스의 변동은 없을 것이다.

그러나 Main클래스가 AnimalType 클래스를 참조하면서, Main클래스와 AnimalType 인터페이스간의 결합도가 생겼다.

Cat을 Dog로 바꾸려면, Main 클래스를 변경해야한다.

<br/>

<br/>

스프링은 해결책을 제시해준다.

Java 코드가 아닌, 외부설정파일을 통해 스프링이 의존성을 주입하여주는 것이다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


	<bean id="Cat" class="com.study.di.Cat"></bean>
	<bean id="Dog" class="com.study.di.Dog"></bean>

	<bean id="PetOwner" class="com.study.di.PetOwner">
		<constructor-arg ref="Dog"></constructor-arg>
	</bean>
</beans>
<br/>
public class Main {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("com/study/di/AppContext.xml");

		PetOwner petOwner = (PetOwner) context.getBean("PetOwner");
		petOwner.doSound();
		
		context.close();
	}
}
<br/>

<br/>

출력

12월 04, 2018 6:37:21 오후 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
정보: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2e817b38: startup date [Tue Dec 04 18:37:21 KST 2018]; root of context hierarchy
12월 04, 2018 6:37:21 오후 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
정보: Loading XML bean definitions from class path resource [com/study/di/AppContext.xml]
멍멍

12월 04, 2018 6:37:21 오후 org.springframework.context.support.ClassPathXmlApplicationContext doClose
정보: Closing org.springframework.context.support.ClassPathXmlApplicationContext@2e817b38: startup date [Tue Dec 04 18:37:21 KST 2018]; root of context hierarchy
<br/>

AppContext.xml 외부설정파일로부터, 객체의 의존을 주입받게된다.

Cat을 Dog로 바꾸려고 하여도 외부설정파일만 변경하면 될 뿐, 어떤 Java 코드의 변경은 없을 것이다.

이렇듯 개발자가 프로그램의 흐름을 제어하는 주체가 아닌, 스프링이 객체의 생성에서부터 생명주기 관리를 맡아서하게된다.

이를** IoC(Inverionf of Control), 제어의 역전** 이라고 한다.

<br/>

그럼 DI를 사용하는 장점이 무엇이 있을까?

  • 방금 설명과 같이 의존도를 낮출 수 있다.

  • 가독성이 상승한다. 외부설정파일을 통해 클래스들간의 의존 관계를 파악 더 쉽게 파악할 수 있다.

  • 테스트에 유용하다. 가상의 Mock객체를 사용하여 의존성을 주입하고 이를 테스트 할 수 있다.
    의존성을 외부설정파일로, 즉 Mock객체를 외부 설정파일로 주입함으로써 소스코드에 변경없이 테스트 할 수 있다.

0
이전 댓글 보기
등록
TOP