오늘의 나보다 성장한 내일의 나를 위해…
IoC 컨테이너와 DI
IoC(Inversion Of Control)의 이해
IoC(제어권의 역전)이란, 객체의 생성, 생명주기의 관리까지 모든 객체에 대한 제어권이 바뀌었다는 것을 의미한다.
IoC(Inversion Of Control): 의존 관계 주입(DI)이라고도 하며, 어떤 객체가 사용하는 의존 객체를 직접 만들어 사용하는 것이 아닌, 주입을 받아서 사용하는 방법
스프링 프레임워크도 객체에 대한 생성 및 생명주기를 관리할 수 있는 기능을 제공하고 있다. 즉, IoC 컨테이너 기능을 제공한다.
IoC 컨테이너의 특징
- IoC 컨테이너는 객체의 생성을 책임지고, 의존성을 관리한다.
- POJO의 생성, 초기화, 서비스, 소멸에 대한 권한을 가진다.
- 개발자들이 직접 POJO를 생성할 수 있지만 컨테이너에게 맡긴다.
IoC의 장점
- 인터페이스 기반 설계가 가능
- 컴포넌트 재사용성 증가
- 체계적이고 효율적인 Dependency 관리
IoC의 단점
- 순환참조가 발생할 가능성이 있다.
- 의존성이 숨어 있다.
IoC의 분류
- DL
저장소에 저장되어 있는 Bean에 접근하기 위해 컨테이너가 제공하는 API를 이용하여 Bean을 Lookup하는 것
아래와 같이 Bean에 대한 정보가 있는 xml 파일이 있다고 해보자.
<beans>
<bean id="myObject" class="com.example.MyObject"/>
</beans>
java에서는 해당 xml의 Bean 정보들을 보고 어떤 클래스를 사용할지 검색하여 주입하게 된다.
아래 자바코드를 보자면
String myConfigLocation = "classpath:myApplicationCTX.xml";
AbstractApplicationContext ctx = new GenericXmlApplicationContext(myConfigLocation);
MyObject myObject = ctx.getBean("myObject", MyObject.class);
그 결과 위와 같은 코드를 통해 적절한 MyObject클래스를 가져올 수 있다.
DL 장점
- JNDI등을 이용하는데 Object간에 Decoupling을 해준다.
DL 단점
- Dependency Lookup으로 획득한 객체는 컨테이너 밖에서 실행할 수 없음
- Bean 변경 시 객체 내에 변경에 대한 부분을 반영해야 하므로 일일이 수정해야 한다 따라서 테스가 어렵다
- 캐스팅이 어렵다. Strong Typed가 아니기 때문에 매번 Casting 해야 한다.
DI
각 클래스간의 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것
- Setter Injection
- Constructor Injection
- Method Injection
DI 장점
- Object가 Container에 의존적이지 않아서 Lookup의 관한 코드가 사라진다.
- 클래스 상속의 필요가 사라지게 된다.
- 코드가 단순해진다.
- 컴포넌트 간 결합도가 낮아진다
- 결합도를 낮추면서 유연성과 확장성 향상
DI 단점
- Spring 내부에 등록된 Bean 끼리만 의존성 설정이 가능하다.
DL 사용시 컨테이너와의 종속이 증가하며, 주로 DI를 사용한다.

DI의 이해
DI의 개념
각 클래스간의 의존관계를 빈 설정 (Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것을 말한다.
개발자들은 단지 빈 설정 파일에서 의존관계가 필요하다는 정보를 추가하면 된다.
객체 레퍼런스를 컨테이너로부터 주입 받아서 실행 시에 동적으로 의존관계가 생성된다.
컨테이너가 흐름의 주체가 되어 애플리케이션 코드에 의존관계를 주입해 주는 것이다.
DI의 장점
- 코드가 단순해진다.
- 컴포넌트 간의 결합도가 낮아진다.
DI의 유형
-
Setter Injection (Setter 메서드를 이용한 의존성 삽입): 의존성을 입력 받는 setter 메서드를 만들고 이를 통해 의존성을 주입한다.
-
Constructor Injection (생성자를 이용한 의존성 삽입): 필요한 의존성을 포함하는 클래스의 생성자를 만들고 이를 통해 의존성을 주입한다.
-
Method Injection (일반 메서드를 이용한 의존성 삽입): 의존성을 입력 받는 일반 메서드를 만들고 이를 통해 의존성을 주입한다.
Spring DI 컨테이너에 대한 이해
Spring 애플리케이션에서 컴포넌트들의 중앙 저장소, Bean 설정 소스로부터 Bean 정의를 읽어들이고 Bean을 구성 하고 제공해주는 컨테이너이다. 또한 실제 IoC 컨테이너는 ApplicationContext 인터페이스를 구현한 클래스의 오브젝트이다.
Spring DI 컨테이너의 개념
Spring DI 컨테이너가 관리하는 객체를 빈(bean) 이라고 하고, 이 빈(bean)들을 관리한다는 의미로 컨테이너를 빈 팩토리(Bean Factory)라고 부른다.
- 객체의 생성과 객체 사이의 런타임(run-time) 관계를 DI관점에서 볼 때는 컨테이너를 BeanFactory라고 한다.
- BeanFactory에 여러 가지 컨테이너 기능을 추가하여 애플리케이션 컨텍스(Application Contect)라고 부른다.
BeanFactory와 ApplicationContext
-
BeanFactory
- Bean을 등록, 생성, 조회, 반환 관리함.
- 보통은 BeanFactory를 바로 사용하지 않고, 이를 확장한 ApplicationContext를 사용한다.
- getBean() 메서드가 정의되어 있다.
-
ApplicationContext
- Bean을 등록, 생성, 조회, 반환 관리하는 기능은 BeanFactory와 같다
- Spring의 각종 부가 서비스를 추가로 제공한다.
- Spring이 제공하는 ApplicationContext 구현 클래스가 여러 가지 종류가 있다.
