Dependency Injection (DI, 의존성 주입)

1. 의존 관계 주입 (dependency injection)

객체간의 의존관계를 객체 자신이 아닌 외부의 조립기가 수행한다.

제어의 역행(inversion of control, IoC) 이라는 의미로 사용되었음.


※ 객체 생성을 프로그래머가 하지 않고 스프링이 하도록 제어권을 넘기는 것을 IoC(제어의 역행)라 한다.

※ 자바에서 인스턴스(객체)라고 불렀던 것을 스프링에서는 Bean이라고 부른다.

스프링에서 생성한 Bean 객체는 필요로 할 때마다 주입 받을 수 있다. 이것이 'DI' 이다.


Martin Fowler, 2004

- 제어의 어떠한 부분이 반전되는가라는 질문에 ‘의존  관계 주입’이라는 용어를 사용

- 복잡한 어플리케이션은 비즈니스 로직을 수행하기 위해서 두 개 이상의 클래스들이 서로 협업을 하면서 구성됨.

- 각각의 객체는 협업하고자 하는 객체의 참조를 얻는 것에 책임성이 있음.

- 이 부분은 높은 결합도(highly coupling)와 테스트하기 어려운 코드를 양산함.


DI를 통해 시스템에 있는 각 객체를 조정하는 외부 개체가 객체들에게 생성시에 의존관계를  주어짐.

- 즉, 의존이 객체로 주입됨.

- 객체가 협업하는 객체의 참조를 어떻게 얻어낼 것인가라는 관점에서 책임성의 역행(inversion of responsibility)임.


느슨한 결합(loose coupling)이 주요 강점

- 객체는  인터페이스에 의한 의존관계만을 알고 있으며,  이 의존관계는 구현 클래스에 대한 차이를 모르는채 서로 다른 구현으로 대체가 가능




2. Spring의 DI 지원 

Spring Container가 DI 조립기를 제공

- 스프링 설정파일을 통하여 객체간의 의존관계를 설정한다.

- Spring Container가 제공하는 api를 이용해 객체를 사용한다.



3. Spring 설정파일

Application에서 사용할 Spring 자원들을 설정하는 파일

Spring container는 설정파일에 설정된 내용을 읽어 Application에서 필요한 기능들을 제공한다.

XML 기반으로 작성한다.

Root tag는 <beans>이다.

파일명은 상관없다.


예) applicationContext.xml

<?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-2.5.xsd">

</beans>





4. Bean 객체 주입 받기 


1) 설정 파일 설정 방식

주입할 객체를 설정파일에 설정한다.

<bean> : 스프링컨테이너가 관리할 Bean객체를 설정


기본 속성 

name : 주입 받을 곳에서 호출 할 이름 설정 

id : 주입 받을 곳에서 호출할 이름 설정 (‘/’  값으로 못 가짐)

class : 주입할 객체의 클래스

factory-method : Singleton 패턴으로 작성된 객체의 factory 메소드 호출 시


<?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-2.5.xsd">

<bean id=“dao” class=“spring.di.model.MemberDAO”/>

</beans>


설정 파일에 설정한 bean을 Container가 제공하는 주입기 역할 api를 통해 주입받는다.


public static void main(String [] args){

     //설정 파일이 어디 있는지를 저장하는 객체

     Resource resource = new ClassPathResource("applicationContext.xml");


      //객체를 생성해주는 factory 객체

     BeanFactory factory = new XmlBeanFactory(resource);


      //설정 파일에 설정한 <bean> 태그의 id/name을 통해 객체를 받아온다.

     MemberDAO dao  = (MemberDAO)factory.getBean("dao");     

}



5. DI관련 주요 클래스 (1/2)


Spring Container : 객체를 관리하는 컨테이너.

다음 아래의 interface들을 구현한다.




Resource 구현 클래스

Resource interface : 다양한 종류의 자원을 동일한 방식으로 통일하여 표현할 수 있게 한다.

XmlBeanFactory는 객체 생성시 설정 파일의 위치를 알려 줘야 한다. (Resource를 이용)


주요 구현 클래스 

org.springframework.core.io.FileSystemResource

파일시스템의 특정 파일의 자원을 관리


org.springframework.core.io.ClassPathResource

클래스 패스에 있는 자원을 관리


org.springframework.web.context.support.ServletContextResource

웹 어플리케이션의 Root 경로를 기준으로 지정한 경로의 자원을 관리

InputStreamResource, PortletContextResource


예) Resource resource = new ClassPathResource("applicationContext.xml");

     BeanFactory factory = new XmlBeanFactory(resource);




설정을 통한 객체 주입 : Constructor를 이용

객체 또는 값을 생성자를 통해 주입 받는다.


<constructor-arg>

- <bean>의 하위태그로 설정한 bean 객체 또는 값을 생성자를 통해 주입하도록 설정

- 설정 방법 : <ref>,<value>와 같은 하위태그를 이용하여 설정, 속성을 이용해 설정

- 하위태그 이용

<ref bean=“bean name”/> : 객체를 주입 시

<value>값</value> : 문자(String), Primitive data 주입 시

type 속성 : 값을 1차로 String으로 처리한다. 값의 타입을 명시해야 하는 경우 사용. ex) <value type=“int”>10</value>

속성 이용

ref=“bean 이름”

value=“값”







Posted by netyhobby
,