Spring - IoC (Inversion of Control), 스프링 - 제어의 역전
스프링의 핵심 기술이자, 많은 참고자료에서 강조되는 것이 바로 IoC (Inversion of Control)라는 기술입니다.
IoC가 도대체 무엇이길래 제일 크게 강조하는지 알아보고자 합니다.
IoC 뜻
IoC는 Inversion of Control의 줄임말입니다.
Inversion은 한국 뜻으로 역전, 전도, 자리바뀜, 뒤집다 등을 의미하며,
Control은 제어, 통제, 지배라는 뜻을 의미하니다.
전체 내용을 번역하면 "제어의 역전" 이라고 번역할 수 있습니다.
제어하는 방식이 원래는 어떻길래 스프링에서는 이를 역전시켰다고 했을까요?
일반적으로 소프트웨어 개발을 할때, 프로그램의 제어 흐름을 컨트롤하는것은 개발자가 합니다.
하지만, 프레임워크에서 내가 작성한 코드를 대신 실행하여 제어 흐름을 컨트롤 하는것이 제어의 역전이라 할 수 있습니다.
이에 대해 좀 더 자세히 알아보겠습니다.
일반적인 제어의 흐름
일반적으로 소프트웨어 개발을 할 때,
개발자가 프로그램의 제어 흐름을 스스로 컨트롤 하는것이 자연스럽습니다.
다양한 자동차를 주행하는 시뮬레이션 코드를 작성해보겠습니다.
아래 예제 코드와 같이 작성을 할 수 있을 것입니다.
Car 클래스를 분리하고, 현대라는 차를 생성하여 main에서 이를 생성하여 car.drive()를 호출합니다.
이것이 일반적으로 프로그램을 개발하는 방식입니다.
public static void main(String[] args) {
Car car = new Car("현대");
car.drive();
}
public class Car {
private String name;
public Car(String name) {
this.name = name;
}
public void drive() {
System.out.printf("Driving Car : " + name);
}
}
이 예제코드에서 만일 다른 Car를 사용하고자 한다면 main 코드를 수정해야합니다.
(Car car = new Car("현대"); 부분을 수정해야합니다.)
IoC에서 제어의 흐름
IoC 패턴으로 만들어진 spring 프레임워크에서는 main 코드를 수정하지 않고도 다른 차를 사용할 수 있게 만들 수 있습니다.
우선, 프레임워크의 코드는 아래와 같이 이미 개발되어 있습니다.
public class IOCExample {
private static final ApplicationContext
context = new ClassPathXmlApplicationContext("basic-context.xml");
public static void main(String[] args) {
Car car = context.getBean(Car.class);
car.drive();
}
}
개발자가 수정해야할 것은 context.xml 파일에서
Car 클래스를 사용하는 Bean에 대한 설정값만 바꿔주면 간단히 어떠한 차든 사용할 수 있습니다.
<!--?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 class="com.spring.examples.Car">
<constructor-arg value="현대">
</constructor-arg>
</bean>
</beans>
내가 main 을 코딩하지 않고, 이미 프레임워크에 구현되어있는 main에서 drive가 호출되는,
즉 프레임워크가 제어의 흐름을 관리하기에 이를 제어의 역전이라고 합니다.
(main 은 개발자가 코딩하는 부분이 아닌, framework에서 이미 개발되어 있는 부분입니다.)
Spring에서의 IoC
Spring에서 IoC를 수행하는 컴포넌트를 IoC container, 혹은 Spring Container라고도 부릅니다.
Spring Container는 객체를 생성하고, 객체끼리 연관짓고, 객체의 생명주기를관리하는 등의 역할을 합니다.
Spring Container에서는 Dependency Injection 방법으로 각 객체들끼리 연관을 지어 전체 application 을 동작하도록 만듭니다.
Dependency Injection은 https://devscb.tistory.com/77 에 설명이 되어있습니다.
앞서 본 예제와 같이, metadata(xml)파일과 POJO(plain old java object, 위 예제에서 Car클래스)를 사용하여 완전한 소프트웨어를 만들어 냅니다.
사용자는 metadata와 POJO를 적절히 사용하기만 하면 쉽게 전체 프로그램 개발을 할 수가 있는게 되는것입니다.
IoC를 사용한 이유? 장점
Spring에서 IoC를 도입한 이유는 바로 의존성(dependency)을 줄이기 위해 도입했다고 볼 수 있습니다.
앞서 본 에제 코드에서 다른 Car를 사용하려고 하면 main코드를 바꿔야 했습니다.
이는 main 코드는 Car라는 클래스에 종속성이 있는 상태입니다.
하지만, IoC를 사용한 코드에서는 단순히 xml코드에서 설정값만 바꾸면 main 코드를 바꾸지 않아도 됩니다.
main코드는 Car와 연관이 있긴하지만, 다른 객체를 사용한다고 해서 main 코드를 바꾸지는 않아도 되는 장점이 있습니다.
이러한 설명에 보듯, 의존성이 줄어들면 유지보수시 수정되는 코드 수가 줄어 들어 개발시간이 단축됩니다.
또한, 기존에 빌드했던 바이너리/클래스들을 다시 빌드를 하지 않아도 되니 빌드시간도 줄어듭니다.
변경사항도 적으니 변경점 발생시 테스트해야 되는 범위도 줄어듭니다.
여러가지로 전체적인 개발시간이 단축되기에 IoC 패턴을 도입했다고 볼 수 있습니다.
총평
의존성 주입이라는게 작은 프로젝트에서는 생각보다 이해하기 어렵고 단번에 설계하기 어렵다고 느낄 수 있습니다.
하지만 규모가 계속 커지는 프로젝트라면 그 효과는 엄청나게 차이가 나게 됩니다.
Spring이 이토록 유행하게 된것은 IoC를 잘 도입해서 어느정도 틀은 제공하되,
내가 원하는 로직/객체를 쉽게 넣을 수 있도록 한것이 가장 큰 영향이 있지 않나 싶습니다.
또한, 이를 위해 third party library도 쉽게 개발할 수 있고,
개발자들도 쉽게 이를 가져다 쓸 수 있기에 Spring을 안쓰면 오히려 개발하기도 불편하고 개발기간도 너무 늘어나는 경향이 있었을 것입니다.
이러한 연유로 많은 개발자들이 사용하게 되고,
그 영향으로 Spring에 익숙한 개발자가 많아져서 Spring 프로젝트도 많아지는 선순환이 계속되어 Spring이 계속 번성하게 된것 같습니다.
저 또한 Java 로 신규 프로젝트를 개발한다고 하면, 개발자 구하기도 쉽고 어느정도 정형화된 틀로 품질을 유지할 수 있는 Spring도입을 먼저 도입할것으로 생각할것입니다.
앞으로도 Spring에 대한 내용을 계속해서 정리해보겠습니다.
#spring,#IoC,#inversion,#control,#dependency,#injection,#DI,#스프링,#제어,#역전,#제어의역전,#디펜던시,#인젝션,#의존성,#주입,#의존성주입
댓글