IoC Container

@Wonyu· February 26, 2025 · 5 min read

IoC Container는 객체의 생성, 관리 및 DI(Dependency Injection)을 담당하는 핵심 요소이다.

📌 IoC(Inversion of Control)

객체의 생성 및 제어 흐름을 개발자가 직접 관리하지 않고, 외부에서(컨테이너가) 관리하는 디자인 패턴

Bean

Spring에서 IoC Container에 의해 관리되는 객체

핵심 개념

✅ IoC Container는 DI를 통해 객체 간 의존 관계를 느슨하게 만든다.
🔹 전통적인 방식

public class Car {
    private Engine engine;

    public Car() {
        this.engine = new Engine();
    }
}

Car 객체에 필요한 Engine() 객체를 직접 생성해 Car 객체가 Engine 객체에 강결합되어있다.

🔹 IoC 방식

@Component
public class Engine {
    public void start() {
        System.out.println("Engine Started!");
    }
}

@Component
public class Car {
    private final Engine engine;

    @Autowired
    public Car(Engine engine) { 
        this.engine = engine;
    }
}

IoC Container가 Car 객체에 Engine 객체를 주입(DI)해 결합을 느슨하게 만든다.

🔹 장점

  1. 결합도 감소
  2. 객체 관리 자동화
  3. 유지보수성 증가

Bean 등록 방법

Spring IoC 컨테이너에서 Bean을 등록하는 방법은 크게 세 가지가 있다.

방법 설명 사용 예시 특징
XML 기반 설정 beans.xml 파일을 사용하여 Bean을 정의 <bean id="myBean" class="com.example.MyBean"/> Spring의 초창기 방식으로 최근 거의 사용되지 않음
Java 기반 설정 @Configuration + @Bean 사용 @Bean public MyBean myBean() { return new MyBean(); } Java 코드만으로 설정 가능해 가독성이 좋아 일부 경우 사용됨
Annotation 기반 설정 (자동 스캔) @Component, @Service, @Repository, @Controller 사용 @Component public class MyBean {} 가장 많이 사용됨

DI 방식

🔹 생성자 주입

@Component
public class Car {
    private final Engine engine;

    @Autowired 
    public Car(Engine engine) {
        this.engine = engine;
    }
}

장점

  • 불변성 보장: final 필드를 사용해 값이 변경되지 않도록 함
  • 의존성 누락 방지: Bean 생성 시 주입이 강제됨
  • 순환 의존성 감지 가능: 애플리케이션 실행 시 순환 의존성을 바로 감지해 예외 발생

🔹 필드 주입

@Component
public class Car {
    @Autowired
    private Engine engine;
}

장점

  • 코드가 간결
  • 테스트 시 쉽게 Mocking 가능(@MockBean 사용 가능)

단점

  • 불변성 보장X
  • DI가 강제되지 않음: 객체가 생성된 후에도 null일 가능성이 있음
  • 순환 의존성 감지 어려움: 실행 중 예외가 발생할 수 있음 필드 주입은 권장되지 않는다.

🔹 세터 주입

@Component
public class Car {
    private Engine engine;

    @Autowired
    public void setEngine(Engine engine) {
        this.engine = engine;
    }
}

장점

  • 선택적 의존성 주입 가능: 필요할 때만 의존성을 변경할 수 있음
  • Spring 컨텍스트 없이도 객체 생성 가능: 테스트에 용이

단점

  • 필드가 null일 수 있음: 주입하지 않으면 런타임 오류 발생 가능
  • 객체의 일관성을 유지하기 어려움: 생성 후에도 값이 변경될 가능성이 있음

⭐️ Spring Boot 공식 문서에도 생성자 주입을 권장


📌 Container의 종류

BeanFactory

✅ 가장 기본적인 IoC 컨테이너 인터페이스

🔹 Bean 생성 시점
getBean() 호출 시 생성

ApplicationContext

✅ BeanFactory를 확장한 형태로, 보다 다양한 기능 제공

🔹 Bean 생성 시점
컨테이너 초기화 시점에서 미리 생성

🔹 장점

  • AOP 지원 (Transaction, Security와 쉽게 결합 가능)
  • Event 시스템과 통합
  • 국제화(i18n) 지원을 통한 다국어 메시지 관리

Spring Boot에서는 자동으로 ApplicationContext를 IoC 컨테이너로 사용한다.


📌 동작 과정

  1. 설정 파일(XML, Java Config, Annotation) 읽기
  2. Bean 등록 (Bean Definition 생성)
  3. Bean 객체 생성 및 초기화 (@PostConstruct, InitializingBean 등)
  4. 의존성 주입 (DI 적용)
  5. 애플리케이션 실행 후 Bean 사용
  6. 애플리케이션 종료 시 Bean 소멸 (@PreDestroy, DisposableBean 등)

📌 참고

https://docs.spring.io/spring-framework/reference/core/beans.html

@Wonyu
Hello :) I'm Wonyu