Springbeginner검토 2026.08

IoC와 Spring Container

객체 생성·연결·수명 제어를 Application 코드에서 Container로 역전한다.

#IoC#ApplicationContext#BeanFactory#Bean

Overview

IoC(Inversion of Control)는 객체가 필요한 협력자를 직접 만들고 전체 흐름을 통제하던 책임을 Framework나 Container에 넘기는 설계 원리다. Spring Container는 Bean 정의를 읽고 객체를 생성·연결·후처리·관리한다.

한 문장 설명: “내가 부품을 찾아 조립”하던 코드를 “조립 공장이 완성품을 공급”하도록 뒤집는 것이다.

핵심 용어

용어설명
BeanSpring Container가 생성·관리하는 객체
BeanDefinitionClass, Scope, 의존성, 초기화 정보의 메타데이터
BeanFactoryBean 조회와 생성의 기본 Container 계약
ApplicationContextEvent, Resource, Message, 자동 후처리를 더한 일반적 Container
Component ScanAnnotation이 붙은 후보를 찾아 BeanDefinition으로 등록

왜 필요한가

객체가 구현 Class 생성까지 책임지면 변경이 전파되고 Test 대역을 넣기 어렵다. Container가 조립을 담당하면 Business 객체는 역할 수행에 집중하고 구성은 Java Config나 자동 설정으로 이동한다.

면접에서는 “누가 객체 그래프를 만들고 책임지는가”로 설명하면 좋다. IoC가 없으면 OrderServicePaymentClient, Repository, 설정값까지 직접 찾아야 한다. IoC가 있으면 ApplicationContext가 객체 그래프를 만들고 OrderService는 주문 처리라는 본래 책임만 가진다.

핵심 원리와 내부 동작

ApplicationContext Refresh 시 Configuration을 읽어 BeanDefinition을 등록한다. BeanFactoryPostProcessor가 정의를 바꿀 수 있고, Bean 생성 과정에서 Dependency Resolution과 BeanPostProcessor 전후 처리가 일어난다. 일부 Bean은 여기서 Proxy로 감싸진다.

flowchart LR; A[Configuration/Scan] --> B[BeanDefinition Registry]; B --> C[BeanFactory]; C --> D[Instantiate]; D --> E[Inject]; E --> F[Post Process / Proxy]; F --> G[Ready Bean]

Example

@Configuration
class AppConfig {
  @Bean
  OrderService orderService(PaymentClient paymentClient) {
    return new OrderService(paymentClient);
  }
}

@ComponentScan은 등록을 자동화할 뿐 IoC 자체와 같은 말은 아니다. Java Config는 객체 구성과 조건을 명시적으로 표현한다.

DI·AOP와의 연결

IoC는 큰 원리, DI는 그 원리를 구현하는 대표 방식이다. Container가 Bean을 만들 때 생성자나 Setter로 협력자를 전달하기 때문에 Business 객체가 협력자를 직접 생성하지 않는다.

AOP도 IoC Container 위에서 자연스럽게 동작한다. Container가 Target Bean을 그대로 노출하지 않고 Proxy Bean으로 감싸서 제공할 수 있기 때문이다. 그래서 Spring이 관리하지 않는 객체를 new로 만들면 DI도 자동으로 안 되고, Proxy 기반 AOP도 적용되지 않는다.

실무에서 발생하는 문제와 Trade-off

암묵적 Scan 범위가 넓으면 의도하지 않은 Bean 충돌이 생긴다. 시작 시 모든 Singleton을 만들면 오류를 조기에 찾지만 Startup과 Memory 비용이 있다. Container 의존 API를 Business 코드 곳곳에 쓰면 Service Locator 형태로 의존성이 숨는다.

흔한 오해

  • IoC와 DI는 같은 말이 아니다. DI는 IoC를 구현하는 대표 수단이다.
  • Spring이 관리하지 않는 new 객체에는 Spring AOP와 Injection이 자동 적용되지 않는다.
  • ApplicationContext에서 Bean을 직접 찾는 것이 항상 좋은 IoC 사용은 아니다.
  • Bean은 무조건 Singleton이 아니며 Scope를 가진다.

Production Considerations

Bean 등록 수와 Startup Step, 실패한 Condition Report를 확인한다. Configuration 경계를 좁히고 동일 Type 후보는 @Primary@Qualifier로 의도를 드러낸다. 무거운 초기화와 외부 연결은 실패·종료 정책을 설계한다.

다른 사람에게 설명한다면

30초: “IoC는 객체 생성과 연결의 제어권을 Application 코드에서 Container로 넘기는 원리입니다. Spring ApplicationContext는 BeanDefinition을 읽어 Bean을 만들고 의존성을 주입하며 후처리와 Lifecycle을 관리합니다.”

2분: 직접 new의 결합 문제, Configuration→BeanDefinition→생성→주입→PostProcessor 흐름과 DI·AOP 연결까지 설명한다. 마지막에는 “IoC 덕분에 객체는 업무 로직에 집중하고, 조립과 부가기능 적용은 Container가 담당한다”로 정리한다.

Interview Questions

  1. IoC와 DI의 차이는?
  2. BeanFactory와 ApplicationContext의 관계는?
  3. BeanDefinition이 필요한 이유는?
  4. Spring 밖에서 만든 객체에 AOP가 적용되지 않는 이유는?

Dependency Injection, Bean Scope와 Lifecycle로 이어간다.

SOURCE REFERENCES

이 문서의 근거

본문은 Dev Atlas 안에서 완결되며, 검증이 필요할 때만 원문을 확인할 수 있습니다.

원문 출처 보기 1