IoC(Inversion of Control)
Anyframe Core는 Spring Framework을 기반으로 Core 기능을 제공하고 있다.
현재 Anyframe Core 3.2.0 에 적용된
Spring Framework의 버전은 2.5.6
이다.
Spring Framework가 가지는 가장 핵심적인 기능이 IoC이다. IoC 개념은 과거에도 많은 곳에서
사용된 개념이지만 최근 Spring Framework과 같은 Lightweight Container 개념이
등장하면서 많은 개발자들에게 관심의 대상이 되고 있다. IoC 개념은 Spring Framework 뿐만
아니라 컨테이너 기능을 가지는 모든 영역에서 사용되고 있는 개념이므로 반드시 이해할 필요가 있다.
IoC(Inversion of Control)개념
IoC는 Inversion of Control의 약자이다. 우리나라 말로 직역해 보면 "역제어"라고
할 수 있다. 제어의 역전 현상이 무엇인지 살펴본다. 기존에 자바 기반으로 어플리케이션을 개발할 때
자바 객체를 생성하고 서로간의 의존 관계를 연결시키는 작업에 대한 제어권은 보통 개발되는
어플리케이션에 있었다. 그러나 Servlet, EJB 등을 사용하는 경우 Servlet
Container, EJB Container에게 제어권이 넘어가서 객체의 생명주기(Life
Cycle)를 Container들이 전담하게 된다. 이처럼 IoC에서 이야기하는 제어권의 역전이란
객체의 생성에서부터 생명주기의 관리까지 모든 객체에 대한 제어권이 바뀌었다는 것을 의미한다.
Spring Framework도 객체에 대한 생성 및 생명주기를 관리할 수 있는 기능을 제공하고
있다. 즉, IoC Container 기능을 제공하고 있다.
Inversion of Control(이하 IoC)이란?
- Component dependency resolution, configuration 및 lifecycle을 해결하기 위한 Design Pattern
- DIP(Dependency Inversion Principle) 또는 Hollywood Principle (Don't call us we will call you)라는 용어로도 사용
- 특정 작업을 수행하기 위해 필요한 다른 컴포넌트들을 직접 생성하거나 획득하기 보다는 이러한 의존성들을 외부에 정의하고 컨테이너에 의해 공급받는 방법으로 동작

이러한 IoC는 다음과 같은 장점을 가지고 있다.
- 클래스 / 컴포넌트의 재사용성 증가
- 단위 테스트 용이
- Assemble과 configure를 통한 시스템 구축 용이
IoC와 Dependency Injection간의 관계
Spring Framework의 가장 큰 장점으로 IoC Container 기능이 부각되어 있으나,
IoC 기능은 Spring Framework이 탄생하기 훨씬 이전부터 사용되던 개념이었다. 그러므로
"IoC 기능을 Spring Framework의 장점이라고 이야기하는 것은 적합하지 않다."고 반론을
제기하면서 "새로운 개념을 사용하는 것이 적합하다."고 주장한 사람이 Martin Flowler이다.
Lightweight 컨테이너들이 이야기하는 IoC를 Dependency Injection이라는 용어로 사용하는
것이 더 적합하다고 이야기하고 있다. Martin Flowler의 이 같은 구분 이후 IoC 개념을 개발자들마다
다양한 방식으로 분류하고 있으나 다음 그림과 같이 IoC와 Dependency Injection 간의 관계를
분류하는 것이 일반적이다.
- Dependency Lookup - 의존 관계에 놓인 특정 리소스를 사용하기 위해 리소스들을 관리하는 Container를 통해 찾는 방법
- Dependency Injection - Setter Injection(JavaBean 유형의 setter 메소드 구현을 통해 초기화 시 Container로부터 의존 관계에 놓인 특정 리소스를 할당 받는 방법)과 Constructor Injection(Constructor 구현을 통해 초기화 시 Container로부터 의존 관계에 놓인 특정 리소스를 할당 받는 방법 )으로 구분
Dependency Lookup
저장소에 저장되어 있는 Bean에 접근하기 위하여 Container에서 제공하는 API를
이용하여 사용하고자 하는 Bean을 Lookup 하는 것을 말한다.
따라서, Bean을 개발자가 직접 Lookup하여 사용함으로써 Container에서 제공하는 API와
의존관계 발생하게 된다.
- 객체 관리 저장소(Repository)
모든 IoC Container는 각 Container에서 관리해야 하는 객체들을 관리하기 위한
별도의 저장소(Repository)를 가진다. Servlet Container는
web.xml에서 Servlet을 관리하고 있으며, EJB Container는
ejb-jar.xml에 설정되어 있는 정보들이 JNDI 저장소에 저장되어 관리되고 있다.
이처럼 Spring Framework도 POJO들을 관리하기 위하여 별도의 저장소로 XML
파일을 가지게 된다.
- Dependency Lookup 예시
구현 클래스는 다음과 같이 작성한다.
public class IoCServiceImpl1 implements IoCService1, ApplicationContextAware {
public void setApplicationContext (ApplicationContext context){
IoCService2 iocService2 = (IoCService2)context.getBean("IoCService2”);
}
}
속성 정의 파일은 다음과 같이 작성한다.
<bean id=”IoCService1” class=”….IoCServiceImpl1”>
//중략
</bean>
<bean id="IoCService2” class="….IoCServiceImpl2”>
//중략
</bean>
}
Dependency Injection (DI)
각 클래스 사이의 의존관계를 빈 설정(Bean Definition)정보를 바탕으로 컨테이너가
자동적으로 연결해주는 것을 말한다. 컨테이너가 의존관계를 자동적으로 연결시켜주기 때문에
개발자들이 컨테이너 API를 이용하여 의존관계에 관여할 필요가 없게 되므로 컨테이너 API에
종속되는 것을 줄일 수 있다. 개발자들은 단지 빈 설정파일(저장소 관리 파일)에서 의존관계가
필요하다는 정보를 추가하기만 하면 된다. 또한 Dependency Injection은
Setter Injection과 Constructor Injection 형태로 구분한다
- Dependency Injection 예시
구현 클래스는 다음과 같이 작성한다.
public class IoCServiceImpl implements IoCService {
public void setDependencyBean(DepBean dependencyBean) {
this.dependencyBean = dependencyBean;
}
//중략
}
속성 정의 파일은 다음과 같이 작성한다.
<bean id="IoCService" class="….IoCServiceImpl">
<property name="dependencyBean" ref="depBean"/>
</bean>
Dependency Lookup과 Dependency Injection의 차이점
Bean을 개발자가 직접 Lookup하여 사용하는 것을 Dependency Lookup이라고
하고, Dependency Injection은 이와 달리 각 계층 사이, 각 클래스 사이에
필요로 하는 의존관계가 있다면 이 같은 의존관계를 Container가 자동적으로 연결시켜주는
것을 말한다. Dependency Lookup을 사용할 경우 Bean을 Lookup하기 위하여
Container에서 제공하는 API와 의존관계가 발생한다. 이처럼 Container API와
많은 의존관계를 가지면 가질수록 어플리케이션이 Container에 대하여 가지는 종속성은
증가할 수 밖에 없다. 따라서 가능한 Dependency Lookup을 사용하지 않는 것이
Container와의 종속성을 줄일 수 있게 된다. Container와의 종속성을 줄이기 위한
방법으로는 이후에 다루게 될 Dependency Injection(본 매뉴얼의 Spring >> IoC >>
Dependencies
참조)
을 통하여 가능하게 된다.