본문 바로가기
개발하자/Spring

DI(Dependency Injection)이란?

by ulqaef 2020. 3. 26.
728x90

Dependcy Injection: DI를 우리말로 번역을 하면 보통 "의존성 주입"이라는 말로 번역을 한다.

여기서 "의존성 주입"을 이해하기 위해 "의존성"과 "주입"을 나누어 생각해 보겠다.

 

"의존성(Dependency)"이란, 예를 들어 Pet이라는 객체가 Animal이라는 객체를 참조하고 있다면 Pet객체는 Animal객체에 의존성을 가진다고 한다.

 

예제 코드를 보면 

public class Pet {
    
    private Animal animal;
    ..
    ..
    animal = new Animal();
    /* 중략 */
}

Pet클래스의 필드에 Animal타입의 animal변수를 멤버변수로 가지고 있으며 Pet객체는 Animal객체를 참조하고 있는 것이다.(의존성을 가진다)

 

위의 코드처럼 한 객체가 다른 객체를 직접 참조하는 방식은 문제를 발생시키게 된다.

  • Pet객체는 Animal객체를 직접 참조하고 있기 때문에 긴밀한 결합(Coupling)이 생기며 Animal객체를 변경하면 Pet객체도 변경해댜 한다.
  • 만약 Animal객체를 참조하는 객체가 많다면 Animal객체가 변경될 시 모두 수정해주어야 한다.

 

"주입(Injection)"은 위의 내용처럼 Pet객체가 Animal객체를 직접 참조하는 것이 아니라 Pet객체의 외부에서 Animal객체를 주입시키는 것이다.

 

Dependency Injection(의존성 주입)은 결국 객체 내부가 아닌 Framework(외부)에 의해 객체가 주입되는 형태라고 할 수 있으며 결국 Framework에 의해 객체가 주입되므로 객체 간의 결합도(의존성)이 줄어들게 된다.

 

여기서 Inversion of Control(제어의 역전)이라는 개념도 등장하게 된다. 

한 객체가 자신이 참조해야할 객체를 직접 생성하고 제어하는 것이 아닌 외부의 컨테이너로 그 제어권을 넘겨주고 있기 떄문에 Inversion of Control(제어의 역전)이라고 한다.

 

 

[ Dependency Injection(의존성 주입) 방식  - xml 설정방식] 

  • 생성자 인젝션 이용하기

첫 번째는 생성자를 이용하여 주입받는 방식이다. 스프링 컨테이너는 XML Configure파일에 등록된 클래스를 찾아서 객체를 생성할 때 기본적으로 default생성자를 호출하지만 컨테이너가 기본 생성자 말고 매개변수를 가지는 생성자를 호출하도록 할 수 있는데 이를 이용하여 생성자 인젝션을 처리하게 된다. 생성자 인젝션을 사용하여 생성자의 매개변수로 의존관계에 있는 객체의 주소 정보를 전달한다.

 

Pet클래스로 예를 들면,

public class Pet {
    
    private Animal animal;
    
    public Pet(Animal animal) {
        this.animal = animal;
    }
}

Pet class의 생성자의 매개변수로 Animal클래스 타입의 animal의 주소정보를 Pet class 필드의 멤버변수 animal에 저장하여 초기화 해주고 있다.

 

이를 위해서는 XML Configure파일에 다음과 같이 설정해 주어야 한다.

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

	<!-- Root Context: defines shared resources visible to all other web components -->    	
	<bean id="pet" class="com.spring.example.Pet">
		<constructor-arg ref="animal" />
	</bean>
	
	<bean id="animal" class="com.spring.example.Animal" />
</beans>

 

 

  • Setter 인젝션 이용하기

Setter 인젝션을 이용하기 위해서는 Pet 클래스에 setter메서드를 추가한다.

public class Pet {
    private Animal animal;
    
    public Pet() {
     /* default constructor */
    }
    
    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}

Setter메서드는 스프링 컨테이너가 자동으로 호출하며 호출하는 시점은 <bean>객체 생성 직후이다. 따라서 Setter 인젝션이 동작하려면 Setter 메서드뿐만 아니라 기본 생성자도 반드시 필요하다.

 

Setter 인젝션을 이용하려면 XML Configure 파일에 <construct-arg> 엘리먼트 대신에 <property>엘리먼트를 사용해야 한다.

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

	<!-- Root Context: defines shared resources visible to all other web components -->    	
	<bean id="pet" class="com.spring.example.Pet">
		<property name="animal" ref="animal"></property>
	</bean>
	
	<bean id="animal" class="com.spring.example.Animal" />
	
</beans>
728x90
반응형

댓글


`