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)해 결합을 느슨하게 만든다.
🔹 장점
- 결합도 감소
- 객체 관리 자동화
- 유지보수성 증가
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 컨테이너로 사용한다.
📌 동작 과정
- 설정 파일(XML, Java Config, Annotation) 읽기
- Bean 등록 (Bean Definition 생성)
- Bean 객체 생성 및 초기화 (
@PostConstruct, InitializingBean 등) - 의존성 주입 (DI 적용)
- 애플리케이션 실행 후 Bean 사용
- 애플리케이션 종료 시 Bean 소멸 (
@PreDestroy, DisposableBean 등)
📌 참고
https://docs.spring.io/spring-framework/reference/core/beans.html