IoC / DI에 대하여..

김건우·2024년 3월 28일

개발 이야기

목록 보기
2/14

❗️ IoC / DI 는 Spring의 중요한 특징 중 하나이며 이를 통해 낮은 결합도를 지닌 어플리케이션을 개발 할 수 있도록 해준다.

🧐 IoC?

IoC는 Interver of Control의 약어로 한국어로 번역하면 "제어의 역전"이라는 뜻을 가지고 있다. 즉 메서드나 객체의 호출작업을 개발자가 아닌 외부에서 결정짓는 것을 의미한다.

원래는 객체 생명주기(객체의 생성, 메서드 호출, 소멸)를 개발자가 직접 관리를 하는 것이 일반적인 프로그램이다. 라이브러리를 불러오더라도 해당 라이브러리의 메서드의 호출과 소멸 등을 직접 관리를 한다.

하지만 스프링의 경우 그 반대이다. 개발자가 객체를 구현하기만 한다면, 호출되는 시점과 소멸되는 시점은 신경쓰지 않아도 된다. 예를 들어 Controller, Service, Repository 같은 객체들을 어너테이션을 통해 구현 후 선언만 해놓는다면 스프링에서 알아서 객체를 생성, 메서드를 호출하고 관리한다.

이처럼 프로그램의 제어권이 스프링 같은 외부 프레임워크로 양도되는 것을 "제어권이 역전되었다"라고 하며 이를 IoC라고 부르는 것이다.

이러한 IoC의 장점으로는

  • 프로그램의 진행 흐름과 구체적인 구현이 분리된다.
  • 개발자는 비즈니스 로직에 집중할 수 있다.
  • 구현체 사이의 변경이 용이하다.
  • 객체 간 의존성이 낮아진다.

는 점들이 존재한다.

🤓 DI?

대부분의 경우 IoC와 DI를 같이 쓰는 경우가 많아서 이를 많이들 헷갈리고 또 혼동해서 쓰는 경우가 많다. 하지만 IoC와 DI는 당연히 다른 개념이며 DI는 IoC를 구현하기 위한 디자인 패턴 개념이다.

public class A {
    private B b = new B();
}

위에 코드를 예시로 들자면 A클래스 안에 B클래스로 생성한 b 객체가 존재한다. 그런데 만약 B클래스에 final 변수가 추가된다거나 아예 다른 클래스로 변경되어야 한다면 어떻게 될까?

당연하게도 에러가 나면서 동작하지 않을 것이다. 이를 우리는 "A가 B에 의존한다" 라고 말한다.

예시에 경우에는 단순히 두 개의 클래스 관계만 나와있지만 실제 프로그래밍을 하게 될 경우 몇 백개의 클래스를 다뤄야 할 것이다. 이때 이러한 의존성을 지닌 클래스들을 일일히 관리하는 것은 굉장히 비효율적이고 불편하다.

이러한 점들을 보완하기 위한 것이 DI, 즉 의존성 주입이다.

그렇다면 의존성 주입이 뭘까? 자연스럽게 이 의존성을 외부에서 주입해준다는 의미가 된다. 지금은 A 클래스 내부에서 B 객체를 생성하고 있기 때문에 A가 반드시 내부에서 생성한 B 인스턴스에 의존하는 것으로 의존관계가 고정된다.

하지만 아래 코드를 보면

public class A {
    private B b;
    
    public A(B b) {
        this.b = b;
    }
}

여전히 A가 B에 의존하는 것은 똑같지만 의존 대상을 직접 생성하는 것이 아니라 외부로부터 주입받는다, 의존성을 외부로부터 주입받는다고 할 수 있다. 지금은 주입 대상인 B 인스턴스들간의 상태 차이만 있을 뿐이지만 만약 B를 인터페이스로 추상화하고 하면 다양한 구현체가 들어옴으로써 의존성을 다각화할 수 있다.

위 예시처럼 생성자를 통한 의존성 주입도 있지만 Setter, Interface를 활용한 의존성 주입 또한 있다.

그러나 스프링에서 권장하는 것은 생성자 주입이니 참고하기를 바란다.

참고 자료
[Spring DI/IoC] IoC? DI? 그게 뭔데? - Jihoon Oh

profile
백엔드 개발자, 김건우입니다.

0개의 댓글