[Spring] IoC 제어 방식 (Inversion of Control)
- IoC 제어 방식은 뭘까?
- 기존 제어 방식과의 차이점은 뭘까?
- IoC 제어 방식은 왜 좋을까?
스프링을 처음 접하게 되면 가장 먼저, 또 가장 많이 듣는 단어 중 하나가 IoC, 제어의 역전이다.
오늘은 스프링의 IoC 제어 방식에 대해 정리해보고자 한다.
우선, 구글이나 책을 통해 IoC에 대해 찾아보면 아래와 같이 나온다.
IOC (Inversion of Control)
제어의 역전, 말 그대로 "제어권의 흐름이 역전"되는 것이다.
메서드나 객체의 호출 작업을 개발자가 결정하는 것이 아니라 외부에서 결정되는 것을 의미한다.
Spring IOC controller에게 의존성을 위임하여 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 한다.
가독성을 향상시키고 코드 중복을 최소화해 유지 보수성을 향상시킨다.
IoC가 코드의 유연성을 높여 개발의 품질을 향상시킨다는 것은 대충 알겠는데,
그렇다면, 기존 제어 방식과 도대체 어떻게 다르길래 코드의 품질을 높일 수 있는 것일까?
기존 제어 방식과의 차이
기존의 제어 방식

다음과 같이 Tool이라는 인터페이스가 존재하고 이를 구현한 Hammer와 Spade라는 클래스가 존재한다고 하자.
기존 제어 방식에서는 사용자가 망치를 사용하기 위해 Hammer 객체를 생성해서 객체의 work 메서드를 호출한다.
만약 망치에서 삽으로 컴포넌트를 변경하고 싶다면 객체 선언부에 대해 new Hammer()에서 new Spade()로, 코드 수정이 불가피하게 필요하다.
package test;
import model.Hammer;
public class TestUser {
public static void main(String[] args) {
//Hammer tool = new Hammer();
//Hammer를 Spade로 변경
Spade tool = new Spade();
tool.work();
}
}
이렇게 사용하고자 하는 컴포넌트의 변경이 필요할 때마다 직접 코드 구현부를 수정해야 하므로 컴포넌트와 사용자의 관계상에서 결합도가 높다. 지금과 같이 해당 컴포넌트가 사용되는 곳이 한 곳인 경우에는 문제가 없겠지만, 여러 곳에서 사용되고 있는 컴포넌트를 교체해야 한다면 코드를 일일이 찾아 바꿔줘야하는 상상만해도 고통인 노동이 생긴다. 즉, 해당 코드는 유지보수성이 낮다고 볼 수 있다.
IoC의 제어 방식
스프링에서는 설정파일에 객체를 Bean으로 등록해 놓으면 시스템 시작시에 로딩해서 필요한 객체를 생성해두고 어플리케이션에서 필요시 해당 객체를 요청하면 IOC 컨테이너를 통해 해당 객체를 반환해준다.
1. 필요한 객체를 Bean으로 등록하는 xml을 작성하여 IoC 컨테이너를 설정한다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- <bean id ="tool" class="model.Hammer"></bean> -->
<bean id ="tool" class="model.Spade"></bean>
</beans>
2. 필요로 하는 의존대상은 IOC 컨테이너로부터 확보한다.
public static void main(String[] args) {
ClassPathXmlApplicationContext factory = new ClassPathXmlApplicationContext("ioc.xml");
Tool tool = (Tool)factory.getBean("tool");
tool.work();
factory.close();
}
이렇게 IoC 방식을 통해 제어하게 되면 Hammer에서 Spade로 컴포넌트를 변경하고 싶더라도 구현부의 소스코드는 수정하지 않고, IoC 컨테이너의 설정파일(xml)만 수정하면 된다. Spring IOC controller에게 의존성을 위임하여 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하는 것이다. 결과적으로 유지보수성이 좋고 테스트가 용이한, 확장성, 이식성이 좋은 코드를 작성할 수 있다.