IOC(Inversion of Control)이란?
Inversion Of Control이란 '제어의 역전'을 의미한다.
자바 초창기에는 자바객체를 생성하고 객체간의 의존관계를 연결하는 등의 제어권이 오롯이 개발자 본인에게 있었지만, 서블릿등이 등장하면서 개발자의 제어권이 서블릿과 EJB를 관리하는 외부 컨테이너로 넘어갔고 객체의 생성부터 생명주기의 관리까지 모든 객체에 대한 제어권이 프레임워크로 바뀐 것을 IOC, 제어의 역전이라고 한다.
일반적인 객체지향 프로그램에서는 객체를 사용하는 시점에 직접 객체를 생성하여 사용한다.
그러나 소스코드상에서 직접 하드 코딩한 객체 생성은 객체간의 의존성을 심화하고 객체간의 결합도를 높아지게 하는 현상을 띠게 하는데 이러한 경우 객체 생성에 있어서 특정 클래스가 변경이 되었을때, 변경이 된 부분에 한하여 의존성을 가지고 있는 해당 클래스를 일일히 수정해야하는 난감한 상황이 벌어지게 된다.
그렇기 때문에 현재 대부분의 프로그램은 IOC에 객체 생성 책임을 위임하고 있다. IOC는 객체 생성 책임을 IOC컨테이너에게 위임하여 객체간의 결합도를 낮추며(loose coupling), 기존 로직에서 객체를 생성하는 로직을 제거하고 Dependency Lookup 혹은 Dependency Injection을 수행한다. (보통 Dependency Injection을 주로 사용한다고 한다.)
여기서 DI(Dependency Injection)는 '의존 관계 주입'을 뜻하며 클래스 사이의 의존관계를 빈 설정 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것을 의미한다. DI를 통해 외부에서 객체를 생성하는 시점에 IOC컨테이너 측에서는 참조하는 객체에게 의존관계를 제공한다. 그렇기 때문에 개발자들이 제어를 담당할 필요 없이 빈 설정파일에 의존관계의 필요성만 명시해주면 된다.
이 Dependency Injection은 보통 3가지 종류로 동작하는데
setter를 통한 주입 방법(Setter Injection)
생성자를 통한 주입 방법(Constructor Injection),
Method를 통한 주입방법(Method Injection)이 있다.
Setter Injection은 의존성을 입력받는 setter메소드를 만들고 이를 통해 의존성을 주입하는 방법이고,
Constructor Injection은 필요한 의존성을 포함하는 클래스의 생성자를 만들고 주입하며,
Method Injection은 의존성을 입력받는 일반 메서드를 만들고 이를 통해 의존성을 주입받는 방법이다.
IOC / DI 의 적용되지 않은 경우와 적용된 경우(setter 주입)의 사례를 들자면 다음과 같다.
// IOC / DI 가 적용되지 않은 경우
public class Takoyakki{
private Octo octo;
public Takoyakki(){
octo = new RedOcto();
}
}
// IOC / DI가 적용된 경우
// 컨테이너
<beans>
<bean id="octo" class="jp.co.food.RedOcto"/>
<bean id="takoyakki" class="jp.co.food.Takoyakki">
<property name="octo" ref="octo" />
</bean>
</beans>
// 애플리케이션 코드
package jp.co.food
public class Takoyakki{
private Octo octo;
public void setOcto(Octo octo){
this.octo = octo;
}
}
setter로 적용 시켜줄 때 IOC컨테이너 측에서 해당 객체(new RedOcto();)를 생성해서 주입시킨다.
<Spring에서 IOC를 담당하는 컨테이너>
여기서 Spring이 IoC방식으로 관리하는 오브젝트를 'bean'이라고 하며 스프링이 'bean'에 대한 생성과 제어를 담당하게 된다. 기본적으로 bean은 singleton bean으로 생성된다.
그리고 이 bean들을 관리하게 되는 컨테이너를 빈 팩토리(BeanFactory)라 하는데, BeanFactory는 여러 유형의 빈을 생성 및 제공해주며 객체 간의 연관관계를 설정하고 클라이언트의 요청시 빈을 생성하는 등 빈의 라이프사이클을 관리한다.
이러한 BeanFactory에 여러가지 기능을 추가한 컨테이너를 ApplicationContext라 부르며, BeanFactory가 제공하는 모든 기능을 제공해주고 컨테이너 생성시 모든 빈 정보들을 메모리에 로드하는 역할을 수행한다.
WebApplicationContext는 웹환경에서 사용할때 필요한 기능이 추가된 애플리케이션 컨텍스트이다.
+) 하나의 애플리케이션은 IOC컨테이너에 의해 POJO클래스(buisness objects로 가장 기본적인 형태의 자바클래스를 뜻한다)와 설정 메타정보가 결합되어 만들어진다.
설정 메타정보는 xml문서, 어노테이션, 자바코드등으로 구성되어 있으며, 애플리케이션을 구성하는 객체 사이의 상호 의존성을 나타낸다.
'Spring' 카테고리의 다른 글
ClassPathResource (0) | 2022.02.14 |
---|---|
thymeleaf에서 스프링 환경변수 사용하기 (0) | 2022.01.28 |
@JsonProperty (0) | 2022.01.28 |
Spring - @Autowired와 빈 객체 탐색 순서 (0) | 2021.05.29 |
스프링- 스프링 Bean, 생성과정과 스코프 (1) | 2021.05.18 |