반응형
Notice
Recent Posts
Recent Comments
관리 메뉴

개키우는개발자 : )

IoC 컨테이너와 DI(Dependency Injection) 본문

JAVA/Spring Framework

IoC 컨테이너와 DI(Dependency Injection)

DOGvelopers 2019. 2. 6. 00:36
반응형

Spring Framework IoC 컨테이너와 

DI(Dependency Injection)


학습 목표


  • IoC(Inversion of Control)의 이해
  • DI(Dependency Injection)의 이해
  • Spring DI 컨테이너에 대한 이해



1.IoC(Inversion of Control)의 이해



1-1 IoC의 개념


IoC(제어권의 역전)이란, 객체의 생성, 생명주기의 관리까지 모든 객체에 대한 제어권이 바뀌었다는 것을 의미한다.


- 컴퓨넌트 의존관계 결정 (Component dependency resolution), 설정(configuration) 및 생명주기(lifecycle)를 해결하기 위한 디자인 패턴(Design Pattern)



1-2 IoC의  컨테이너


스프링 프레임워크도 객체에 대한 생성 및 생명주기를 관리할 수 있는 기능을 제공하고 있음. 즉, IoC 컨테이너 기능을 제공한다.


- IoC 컨테이너는 객체의 생성을 책임지고, 의존성을 관리한다.


- POJO의 생성, 초기화, 서비스, 소멸에 대한 권한을 가진다.


- 개발자들이 직접 POJO를 생성할 수 있지만 컨테이너에게 맡긴다.



1-3 IoC의  분류


DL(Dependency Lookup) 과 DI(Dependency Injection)

- DL : 저장소에 저장되어 있는 Bean에 접근하기 위해 컨테이너가 제공하는 API를 이용하여 Bean을 Lookup 하는 것


- DI : 각 클래스간의 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것

1. Setter Injection

2. Constructor Injection

3. Method Injection


DL 사용시 컨테이너 종속이 증가하여, 주로 DI를 사용함.


ioc 설명 이미지ioc 설명 이미지




2.DI(Dependency Injection)의 이해



2-1 DI의 개념


각 클래스간의 의존관계를 빈 설정 (Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것을 말함.


- 개발자들은 단지 빈 설정파일에서 의존관계가 필요하다는 정보를 추가하면 된다.


-객체 레퍼런스를 컨테이너로부터 주입 받아서, 실행 시에 동적으로 의존관계가 생성된다.


-컨테이너가 흐름의 주체가 되어 애플리케이션 코드에 의존관계를 주입해 주는 것이다.


DI 의 장점


- 코드가 단순해진다.

- 컴퓨턴트 간의 결합도가 제거된다.



2-2 DI의 유형


- Setter Injection (Setter 메서드를 이용한 의존성 삽입) : 의존성을 입력 받는 setter 메서드를 만들고 이를 통해 의존성을 주입한다.


- Constructor Injection (생성자를 이용한 의존성 삽입) : 필요한 의존성을 포함하는 클래스의 생성자를 만들고 이를 통해 의존성을 주입한다.


- Method Injection (일반 메서드를 이용한 의존성 삽입) : 의존성을 입력 받는 일반 메서드를 만들고 이를 통해 의존성을 주입한다.



2-3 DI를 이용한 클래스 호출방식


Hello 클래스 사용한다는 가정하에 구현 클래스의 상위 인터페이스를 사용하며 

구현 클래스의 정보는 xml(설정파일)에 기술 해놓습니다. 그러면 Framework(컨테이너) 에서 설정파일을 읽은후 구현객체를 생성하며 서로 의존관계가 있는지 확인하는 작업은 컨테이너에서 실행해줍니다.



DI를 이용한 클래스 호출방식DI를 이용한 클래스 호출방식



2-4 Setter Injection


Setter InjectionSetter Injection




-Hello 클래스가 Strping printer 을 의존하지만 new String Printer 객체를 선언하지않고 상위 인터페이스인 Printer 타입 을 맴버변수로 선언후 setter 메소드를 생성해줍니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package myspring.di.annot;
 
public class Hello {
 
    private String name;
    private Printer printer;
    
    public Hello() {}
 
    public void setName(String name) {
        this.name = name;
    }
 
    public void setPrinter(Printer printer) {
        this.printer = printer;
    }
 
    public String sayHellow() {
        return "Hello " + name;
    }
 
    public void print() {
        this.printer.print(sayHellow());
    }
    
}
 
cs


- 스프링이 관리해주는 자바 객체를 선언할땐 Bean으로 정의를 합니다. Hello.class 를 매핑하여 

property name 이 setter 맴버의 name,printer 정의해주고 value 에 값을 지정해줍니다.


1
2
3
4
5
6
7
8
<bean id="hello" class="myspring.di.xml.Hello">
    <property name="name" value="Spring Study" />
    <!-- setPrinter(Printer) -->
    <property name="printer" ref="printer" />
</bean>
 
<bean id="printer" class="myspring.di.xml.StringPrinter"/>
<bean id="consolePrinter" class="myspring.di.xml.ConsolePrinter"/>
cs


2-5 Constructor Injection


- setter injection 은 한번에 한개씩 의존관계 주입을 하지만 한번에 여러개의 값을 주입하는방법으로 생성자 를 작성하여 주입도 가능합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package myspring.di.annot;
 
public class Hello {
 
    private String name;
    private Printer printer;
    
    public Hello() {}
    
    //생성자 
    public Hello(String name, Printer printer) {
        super();
        this.name = name;
        this.printer = printer;
    }
 
    public String sayHellow() {
        return "Hello " + name;
    }
 
    public void print() {
        this.printer.print(sayHellow());
    }
    
}
 
cs


- 생성자 방식은 constructor-arg 태그로 값을 정의해줍니다.


1
2
3
4
5
6
7
<bean id="hello2" class="myspring.di.xml.Hello">
    <constructor-arg index="0" value="spring" />
    <constructor-arg index="1" ref="project" />
</bean>
 
<bean id="printer" class="myspring.di.xml.StringPrinter"/>
<bean id="consolePrinter" class="myspring.di.xml.ConsolePrinter"/>
cs


3.Spring DI 컨테이너에 대한 이해



3-1 Spring DI 컨테이너의 개념


Spring DI 컨테이너가 관리하는 객체를 빈(bean)이라고 하고, 이 빈(bean)들을 관리한다는 의미로 컨테이너를 

빈 팩토리(BeanFactory) 라고 부른다.


- 객체의 생성과 객체 사이의 런타임(run-time) 관계를 DI 관점에서 볼 때는 컨테이너를 BeanFactory라고 한다.


- BeanFactory에 여러 가지 컨테이너 기능을 추가하여 애플리케이션 컨텍스(ApplicationContext)라고 부름



3-2 BeanFactory와 ApplicationContext


- BeanFactory

- Bean을 등록,생성,조회,반환 관리함.

- 보통은 BeanFactory를 바로 사용하지 않고, 이를 확장한 ApplicationContext를 사용함.

- getBean() 메서드가 정의되어 있음


- ApplicationContext

- Bean을 등록,생성,조회,반환 관리하는 기능은 BeanFactory와 같음

- Spring의 각종 부가 서비스를 추가로 제공함

- Spring이 제공하는 ApplicationContext 구현 클래스가 여러 가지 종류가 있음



Spring DI 컨테이너에 대한 구조Spring DI 컨테이너에 대한 구조



반응형

'JAVA > Spring Framework' 카테고리의 다른 글

DI 애플리케이션 작성(2)  (0) 2019.02.06
DI 애플리케이션 작성(1)  (0) 2019.02.06
프로젝트 시작하기  (0) 2019.01.30
Spring Framework 의 개요  (0) 2019.01.30
Basic Framework 개념(3)  (0) 2019.01.30
Comments