Spring IoC

제어역전(IoC)와 의존성 주입(DI)

Spring에서 말하는 DI와 IoC는 각기 다른 개념을 설명하는 것이 아니다. DI는 IoC 의 다양한 방법 중 하나이다

일반적으로 IoC는 두 개의 하위 분류로 나눌 수 있다. Dependency Lookup과 Dependency Injection이다. 

그리고 그에 따른 하위분류와 설명은 아래와 같다.


Inversion of Control (IoC)

 Dependency Lookup (DL)

 Dependency Pool (의존성풀)

 Contextualized Dependency Lookup (컨텍스트화된 의존성 룩업 : CDL)

 Dependency Injection (DI)

 Setter Injection

 Constructor Injection

 Method Injection

 

1. Dependency Lookup

IoC컨테이너가 관리중인 객체 저장소(Pool)에서 객체를 검색하여 참조하는 방법. 컨테이너에서 제공하는 api를 이용하여 찾고자 하는 bean을 lookup하는 방법.


1.1 Dependency Pool

JNDI레지스트리 처럼 필요할 때마다 컨테이너가 레지스트리에 요청하여 의존객체를 획득하는 방법. Spring BeanFactory역시 Dependency Pool


[Spring 에서 의존성 Pool]

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) throws Exception { 
 
    // BeanFactory가 Spring Singletone 레지스트리 역할
    BeanFactory factory = getBeanFactory();
    
    // getBean() 을 통해서 lookup 수행
    MessageRenderer mr = (MessageRenderer) factory.getBean("render");
    ...
    // todo something with instance mr
}
cs


1.2 Contextualized Dependency Lookup

Dependency Pool과 유사하지만, 개체를 관리하는 중앙 레지스트가 있는 것이 아니라 리소스(의존객체)를 관리하는 별도의 컨테이너를 대상으로 룩업을 수행하는 방법. (컨테이너는 Application Server 혹은 Framework에서 제공)


[CDL에서 의존성 Lookup]

1
2
3
4
5
6
7
8
9
10
public class ContextualizedDependencyLookup implements ManagedComponent {
    
    private Dependency dependency; // 의존성 주입 target
 
    @Override 
    public void performLookup (Container container) {    // ManagedComponent interface에 정의돈 메소드 구현
        this.dependency = container.getDependency("myDependency"); // was나 fwk 에서 제공하는 container 대상으로 Lookup 
        ...
    }
}
cs


* Dependency Pool과 Contextualized Dependency Lookup 은 특정한 저장소에서 lookup을 수행하여 의존성을 참조한다는 것은 공통적이지만, Dependency Pool은 별도의 레지스트리를 대상으로 Lookup을 수행하고, Contextualized Dependency Lookup은 레지스트리가 아니라 bean을 관리하는 별도의 컨테이너를 대상으로 Lookup을 수행하는 점이 다르다.



2. Dependency Injection 

IoC의 타겟이 되는 객체의 의존성을 직접 소스코드에서 결정하지 않고, 외부화 하여 어떤 의존성을 주입할 것인지 결정하는 방법. 생성자 의존성 주입, 세터 의존성 주입, 메서드 의존성 주입의 방법등이 있고, 책에서는 의존성 룩업보다 훨씬 유연하고 간단한 방법(직관적이지는 않지만)이라고 말한다. 왜냐하면 룩업의 경우는 레지스트리에서 특 정 키로 조회하여 객체를 획득하고 대상 오브젝트를 반드시 캐스팅 할 필요가 있는데 이를 소스코드에서 직접 수행하여 의존성이 발생하게 되고 만다. 하지만 의존성 주입의 경우 별도 파일을 통해서 의존성 타켓과 의존성을 지정하여 주기 때문에 소스코드의 변경없이 의존성 주입 타켓 변경이 가능하다. 


2.1 Constructor Injection

생성자 의존성 주입은 컴포넌트 의존성을 생성자에게 제공하는 의존성 주입 방식이다. 컴포넌트는 의존성을 인자로 받는 Constructor(s)를 선언하고, IoC컨테이너는 컴포넌트 인스턴스를 생성할 때 컴포넌트 의존성을 넘겨준다.

1
2
3
4
5
6
7
8
public class ConstructorInjection {
    private Dependency dependency;
    
    // Constructor
    public ConstructorInjection(Dependency dependency) {
        this.dependency = dependency;
    }
}
cs


2.2 Setter Injection

Setter 의존성 주입 방식을 사용하면, IoC컨테이너가 자바빈 방식의 세터메서드를 통해서 컴포넌트에게 의존성을 주입하여 준다. 이 때 컴포넌트의 Setter는 IoC가 관리할 수 있는 의존성을 노출한다. 가장 많이 쓰이고 책에서도 가장 추천하는 방법이다. 

1
2
3
4
5
6
7
8
public class SetterInjection {
    private Dependency dependency;
    
    // Constructor
    public void setDependency(Dependency dependency) {
        this.dependency = dependency;
    }
}


cs


이 글을 공유하기

댓글

Email by JB FACTORY