컨테이너와 IoC/DI
컨테이너(Container)
- 프레임워크 기반의 프로그램은 프레임워크 자신이 프로그램 실행 흐름을 제어하는 주체가 되어, 필요할 때마다 애플리케이션 코드를 호출하여 사용한다.
- 프레임워크에서 이 제어권을 가지는 것을 컨테이너라고 부른다.
- 객체에 대한 제어권이 개발자로부터 컨테이너로 넘어가면서 객체의 생명주기 관리를 컨테이너가 도맡아서 한다.
- 이를 일반적인 제어권의 흐름이 바뀌었다고 하여 Ioc(Inversion of Control : 제어의 역전)라고 부른다.
WAS의 Servlet 컨테이너
- 예를들어 Servlet을 실행해주는 WAS는 Servlet 컨테이너를 가지고 있다고 말한다.
- WAS는 웹 브라우저로부터 서블릿 URL에 해당하는 요청을 받으면 해당 서블릿을 메모리에 올리고 실행한다.
- 서블릿 클래스를 구현한 것은 프로그래머이지만, 실제로 서블릿 객체를 생성하여 메모리에 올리고 실행하는 것은 WAS의 Servlet 컨테이너다.
- Servlet 컨테이너는 동일한 서블릿에 대한 요청을 받으면 메모리 상에 올라가있는 서블릿을 실행하여 그 결과를 웹 브라우저에 전달한다.
Ioc(Inversion of Control)/DI(Dependency Injection)
- DI는 의존성 주입이란 뜻을 가지고 있으며, 클래스 사이의 의존 관계를 빈(Bean) 설정 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것을 말한다.
- 예를들어 A객체가 동작하기 위해서는 A객체가 B객체를 가지고 있어야 하는 상황이다. 이때 이 B객체를 프로그래머가 작성한 애플리케이션 코드로 직접 생성하는 것이 아니라 컨테이너가 대신 생성해 주는 것이다.
- 개발자들은 제어를 담당할 필요없이 빈 설정 파일에 의존 관계 정보만 추가해주면 된다. 그리고 컨테이너는 이 정보를 기반으로 프로그램 실행시에 동적으로 객체를 만들어서 의존관계를 주입한다.
- 다시 말해 DI는 컨테이너가 프로그램 실행 흐름의 주체가 되어서 애플리케이션 코드에 의존관계를 주입해주는 것이다. 이를 제어의 역전(Ioc)라고 한다.
Ioc/DI가 적용되지 않은 경우
애플리케이션 코드
package kr.co.example;
public class Person{
private Phone phone;
public Person(){
phone = new FeaturePhone();
}
}
- Ioc/DI가 적용되지 않는 경우, Phone 인터페이스를 구현하는 FeaturePhone 클래스를 new 키워드를 통해 직접 생성해서 초기화 하고 있다.
- 이런 경우 동적으로 새로운 구현 클래스를 적용하기가 어렵다.
- 만약 Ioc/DI를 사용한다면, SmartPhone 클래스로 바꾸고 싶을때 빈 설정 정보만 수정해주면 된다.
Ioc/DI가 적용된 경우
컨테이너 빈 설정 정보
<beans>
<bean id = "phone" class="package kr.co.example.Phone">
<bean id = "person" class="package kr.co.example.Person">
<property name="phone" ref="phone"/>
</bean>
</beans>
애플리케이션 코드
package kr.co.example;
public class Person{
private Phone phone;
public Person(Phone phone){
this.phone = phone;
}
}
- 빈 설정 정보를 바탕으로 사용할 객체들을 컨테이너에 등록한다.
- 프로그램을 실행하면 컨테이너는 애플리케이션 코드에 등록한 객체를 넣어준다.
- 즉, Person 객체의 생성자 매개변수로 Phone 객체를 생성해서 넣어준다.
-
이렇게 하면 Phone 인터페이스를 구현하는 클래스가 애플리케이션에 등록하지 않는다. 따라서 동적으로 구현 클래스를 마음대로 바꿀 수 있다.
- Ioc/DI를 사용하면 객체를 생성할 때 해당 객체가 참조하고 있는 다른 객체에 대한 종속성을 애플리케이션 코드 외부에서(컨테이너가) 설정하게 함으로써 결합도(Coupling)를 낮추며 유연성과 확장성을 향상 시킬 수 있다는 장점이 있다.
소프트웨어 공학에서, 결합도(coupling) 또는 의존도는 어떤 모듈이 다른 모듈에 의존하는 정도를 나타내는 것이다.
Spring Container
- 스프링 Ioc 컨테이너가 관리하는 객체를 빈(Bean)이라고 부른다.
- 스프링에서는 이 빈(Bean)들을 관리한다는 의미로 컨테이너를 빈 팩토리(Bean Factory)라고 부른다.
- 스프링의 컨테이너는 단순한 DI 작업뿐만 아니라 더 많은 일을 한다. 그래서 DI 기능에 엔터프라이즈 애플리케이션을 개발하는데 필요한 여러 가지 컨테이너 기능을 추가하여 애플리케이션 컨텍스트(Application Context)라고 부르기도 한다.
- 스프링에서는 xml에 Configuration 정보를 담아 컨테이너를 구성할 수 있다.
참고
- https://www.nextree.co.kr/p11247/