영호

공식문서로 알아보는 IoC container 본문

Spring

공식문서로 알아보는 IoC container

0h0 2023. 4. 20. 19:04

개요

Spring의 IoC container를 알아보기 위해 아래와 같은 개념들에 대해 정리한다.

  • IoC란?
  • Spring에서 IoC를 제공하기 위한 인터페이스
  • IoC컨테이너 안에서 bean을 관리하는 생명주기

IoC(Inversion of control)

위 단어를 해석하면 ‘제어의 역전’이다. 나는 여기서 제어라는 것은 의존성 관리를 의미한다고 생각한다. 객체지향 프로그래밍은 다양한 객체를 생성하고 객체끼리의 의존성을 관리하면서 객체를 사용하는 코드를 작성해 서비스를 구성한다.

만약 A객체에서 B객체의 기능을 사용할 필요가 있어서 A클래스 내부에서 B객체를 생성하는 코드를 작성하게 되면 A와 B는 강하게 결합된다.

class ServiceA {
    public void doSomething() {
    }
}

class ServiceB {
    private ServiceA serviceA;

    public ServiceB() {
        serviceA = new ServiceA(); // ServiceA의 인스턴스를 직접 생성
    }

    public void doSomethingWithA() {
        serviceA.doSomething(); // ServiceA의 메서드를 호출
    }
}
  • 객체를 직접 생성한다.
  • 어떤 구체 클래스에 의존할지 내부적으로 관리하고 있다.

IoC적용

위 코드를 IoC를 적용해 객체의 생성, 의존성 관리 책임을 없애보겠습니다.

interface IService {
    void doSomething();
}

class ServiceA implements IService {
    @Override
    public void doSomething() {
        
    }
}

class ServiceB {
    private IService serviceA;

    public ServiceB(IService serviceA) {
        this.serviceA = serviceA; // IService 인터페이스를 통해 주입받음
    }

    public void doSomethingWithA() {
        serviceA.doSomething(); // IService 인터페이스를 통해 메서드를 호출
    }
}
  • ServiceB는 객체를 생성하지 않는다.
  • serviceA를 필드로 선언하고 있는데 의존성 관리가 없어졌다고 할 수 있나..?
    • 고민해본 결과 인터페이스에 의존하고 있고 어떤 구체 클래스에 의존하는지는 관리하고 있지 않기 때문에 의존성 관리의 책임도 외부로 역전됐다고 생각한다.

IoC == DI??

Spring공식문서를 보면 아래와 같은 문구가 있다.

IoC is also known as dependency injection (DI).

나는 개인적으로 DI는 IoC의 수단으로 활용된다고 생각한다. IoC는 객체 생성과 의존성 주입을 통해 이루어지는데, DI가 객체 생성까지 관여하진 않기 때문이다. 

IoC container

Spring에서 관리하는 객체를 bean이라고 한다. Spring에서는 BeanFactory, ApplicationContext인터페이스를 통해 bean생성과 의존성을 관리해준다.

BeanFactory는 bean을 관리하기 위한 IoC의 기본적인 기능이 정의된 인터페이스다.

ApplicationContext는 BeanFactory의 기능에 더불어 아래 기능을 제공한다.

  • Easier integration with Spring’s AOP features
  • Message resource handling (for use in internationalization)
  • Event publication
  • Application-layer specific contexts such as the WebApplicationContext for use in web applications.

위 내용에 대해선 추가적인 학습이 필요해서 ApplicationContext는 더 많은 기능을 제공하는구나 정도로만 알고 넘어간다.

빈 생명주기 관리

IoC container는 메타데이터를 기반으로 bean인스턴스화, 의존성 주입, 소멸을 진행한다.

여기서 메타데이터란 bean으로 관리할 객체, 객체 간 의존정보를 의미한다. 메타데이터는 3가지 방식으로 작성할 수 있다.

  • XML
  • Annotation
  • JAVA

빈 생명주기

  1. 스프링 컨테이너 생성
  2. 빈 생성 및 등록
    • 생성자 주입의 경우 생성자 파라미터로 객체를 받기 때문에 이 부분에서 의존성 주입이 같이 발생한다.
  3. 의존성 주입
    • 필드 주입, 수정자 주입의 경우 모든 빈을 생성한 뒤 의존성 주입이 발생한다.
  4. 초기화
  5. 소멸

궁금한 점

  • 생명주기 중 초기화 부분에서 bean에 추가적으로 초기화할 정보를 세팅한다고 하는데, 생성자에서 세팅하지 않고 별도의 메서드를 통해 초기화 해야하는 이유가 뭘까?
    • 아직 필요성을 느끼지 못해서 와닿지 않는 부분이다.

출처

Comments