본문 바로가기
Spring Study

IoC(Inversion of Control) 컨테이너

by xogns93 2024. 8. 6.

IoC(Inversion of Control) 컨테이너는 객체의 생성, 구성, 생명주기 관리, 의존성 주입 등을 책임지는 프레임워크입니다. IoC 컨테이너는 애플리케이션의 구성 요소들을 관리하여 코드의 결합도를 낮추고 유연성을 높입니다. 스프링 프레임워크에서 IoC 컨테이너는 애플리케이션의 핵심 구성 요소로, 다양한 빈(Bean)들을 관리합니다.

IoC 컨테이너의 주요 역할

  1. 객체 생성 및 관리:
    • 빈을 정의하고, 이를 생성 및 관리합니다.
  2. 의존성 주입:
    • 빈 간의 의존성을 주입하여 결합도를 낮추고, 코드의 유연성을 높입니다.
  3. 생명주기 관리:
    • 빈의 생명주기를 관리하여 애플리케이션의 자원을 효율적으로 사용합니다.

스프링 IoC 컨테이너

스프링 프레임워크에서 IoC 컨테이너는 ApplicationContext와 BeanFactory를 통해 구현됩니다.

  1. BeanFactory:
    • 스프링의 가장 기본적인 IoC 컨테이너입니다.
    • 지연 로딩(Lazy Loading)을 지원하여, 실제로 빈이 필요할 때 생성합니다.
  2. ApplicationContext:
    • BeanFactory를 확장한 IoC 컨테이너로, 대부분의 애플리케이션에서 사용됩니다.
    • 즉시 로딩(Eager Loading)을 기본으로 하며, 애플리케이션 시작 시 모든 빈을 생성합니다.
    • 추가적인 기능으로 국제화 메시지 지원, 이벤트 전달, 어플리케이션 레벨 설정 등을 제공합니다.

IoC 컨테이너의 동작 방식

스프링 IoC 컨테이너는 설정 파일(XML, Java Config, 어노테이션)을 읽어 빈 정의를 로드하고, 이를 기반으로 빈을 생성하고 관리합니다.

XML 설정을 통한 방식은 요즘 거의 안씀, 어노테이션 기반 설정은 코드 내에 설정을 포함시키므로 가독성과 유지보수성을 높이며, 설정과 비즈니스 로직이 밀접하게 연관되어 있을 때 특히 유용하고 시각적으로 더 직관적입니다.

예제: 어노테이션 설정을 통한 IoC 컨테이너

Engine.java

package com.example;

import org.springframework.stereotype.Component;

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

 

Car.java

package com.example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Car {
    private Engine engine;

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

    public void start() {
        engine.start();
    }
}

 

AppConfig.java

package com.example;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}

 

Main.java

package com.example;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        Car car = context.getBean(Car.class);
        car.start();
    }
}

 

IoC 컨테이너의 장점

  1. 유연성 증가:
    • 객체 간의 의존성을 런타임에 주입할 수 있어 유연성이 증가합니다.
  2. 결합도 감소:
    • 객체 간의 결합도를 낮추어 코드의 재사용성과 유지보수성을 높입니다.
  3. 설정의 일관성:
    • 애플리케이션의 구성 요소를 중앙 집중식으로 관리할 수 있어 설정의 일관성이 유지됩니다.
  4. 테스트 용이성:
    • 의존성 주입을 통해 모킹(Mocking)이나 스텁(Stub) 객체를 쉽게 주입할 수 있어 테스트가 용이해집니다.