본문 바로가기
Back-end/java spring

IoC, DI 그리고 컨테이너 개념 정리

by kkkdh 2022. 12. 28.
728x90

제어의 역전 IoC(Inversion of Control)

제어의 역전은 스프링에만 국한된 단어가 아니라 일반적인 개발자가 모든 것을 제어(control)하는 흐름에서 벗어나 내가 호출하는 것이 아니라 프레임워크 같은 것이 대신 호출해 주는 구조를 의미합니다. (한 마디로 제어에 대한 권한이 뒤바뀌는 것을 의미한다고)

 

기존의 프로그램은 클라이언트 구현 객체가 스스로 필요한 서버 구현 객체를 생성하고, 연결하고 실행하는 구조를 따랐습니다. 한 마디로 구현 객체가 프로그램의 제어 흐름을 스스로 조종하는 구조이며 개발자의 입장에서는 자연스러운 흐름이었죠

 

그런데, 지난번 DI에 대한 정리글에서 설명한 AppConfig가 의존 관계를 주입하는 등의 역할을 가져감으로써, 프로그램에 대한 제어의 흐름을 가져간 바가 있습니다.

 

이렇게 각각의 구현체들은 자신들의 기능 수행에 집중하고, 제어의 흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것을 제어의 역전(IoC)라고 할 수 있습니다.


프레임워크 vs 라이브러리

프레임워크와 라이브러리에 대한 개념의 비교에 제어의 역전 개념이 사용됩니다.

  • 내가 작성한 코드를 프레임워크가 제어하고(제어의 역전이 발생하고), 대신 실행하면 이 것은 프레임워크가 맞고
    (예를 들어 JUnit을 사용하는 것을 프레임워크 사용 예시로 들 수 있습니다. 내 코드는 JUnit의 제어에 따라 일부 사용되는 구조이기 때문입니다.)
  • 반면에, 내가 작성한 코드가 직접 제어의 흐름을 담당한다면, 그것은 라이브러리를 사용하는 것으로 볼 수 있습니다.

의존관계 주입 DI(Dependency Injection)

  • 의존관계 주입이 적용되면, 프로그램 내에서 각 구현체는 구체화가 아닌 추상화에 의존하게 된다. (객체가 아니라 인터페이스에 의존한다는 뜻이다.)
  • 의존관계는 정적인 클래스 의존관계와, 실행 시점에 결정되는 동적인 객체(인스턴스) 의존관계 둘을 분리해서 생각해야 한다.

정적인 클래스 의존관계

정적인 클래스 의존관계클래스가 사용하는 import 코드만 보고 의존관계를 쉽게 판단할 수 있다. 정적인 의존관계는 애플리케이션을 실행하지 않아도 분석할 수 있다.

 

또한 정적인 클래스 의존관계는 클래스 다이어그램으로 도식화가 가능하다.

클래스 다이어그램 예시

클래스 다이어그램을 통해 OrderServiceImpl이라는 구체화가 MemberRepository, DiscountPolicy라는 추상화에 의존하고 있음을 확인할 수 있다.

 

그러나 이러한 클래스 의존 관계 만으로는 실제 프로그램 동작 과정에서 어떤 객체가 OrderServiceImpl에 주입될지 알 수 없다.

 

동적인 객체 의존관계

동적인 객체 의존관계는 애플리케이션의 실행 시점에서 실제 생성된 객체 인스턴스의 참조가 연결된 의존 관계를 의미한다.

 

객체 의존관계는 객체 다이어그램을 통해 도식화 할 수 있다.

객체 다이어그램 예시

  • 애플리케이션 실행 시점(런타임)에 외부에서 실제 구현 객체를 생성하고 클라이언트에 전달해 클라이언트와 서버의 실제 의존관계가 연결되는 것을 의존관계 주입이라고 한다.
  • 외부(AppConfig)에서 객체 인스턴스를 생성하고, 그 참조 값을 전달해서 연결하는 구조이다.
  • 의존관계 주입을 도입하면, 클라이언트 코드를 변경하지 않고, 클라이언트가 호출하는 대상의 타입 인스턴스(구현체, 구체화의 종류)를 변경할 수 있다.
  • 따라서 의존관계 주입의 사용을 통해 정적인 클래스의 의존관계를 변경하지 않고, 동적인 의존관계를 쉽게 변경할 수 있게 된다.
  • 여기서 정적인 의존 관계를 변경하지 않는다는 것은 코드를 변경하지 않아도 됨을 의미한다.

IoC 컨테이너, DI 컨테이너

처음에는 IoC 컨테이너라고 불리다가, IoC라는 개념이 너무나도 범용적으로 적용되는 개념이어서 DI 컨테이너라는 이름으로 바뀌게 되었다고 한다.

 

앞선 설명에서의 AppConfig 같은 컨테이너(의존성을 주입해주는 역할을 담당하는 컨테이너)를 IoC 컨테이너 또는 DI 컨테이너라고 부른다.

 

최근에는 컨테이너의 역할에 대한 의미부여를 더 명확하게 하기 위해서 DI 컨테이너라고 부른다고.. Spring이 DI 컨테이너 역할을 한다. (꼭 Spring 말고도 많은 프레임워크가 이러한 역할을 담당한다.)

 

레고 블럭 조립하듯이 조립한다고 해서 어셈블러라고 하기도 하고, 오브젝트를 만든다고 해서 오브젝트 팩토리라고 부르기도 한다고 한다.


본 개념 정리글은 김영한님의 스프링 핵심 원리 - 기본편 강의 내용을 정리하는 글입니다.

728x90

댓글