
스프링의 의존성 주입(DI)을 이해하려면 먼저 스프링 컨테이너(Spring Container) 가 어떤 역할을 하는지 파악하는 것이 중요합니다.
스프링 컨테이너는 객체(Bean)를 생성하고 관리하며, 필요한 의존관계를 연결해주는 핵심 엔진입니다.
이번 글에서는 스프링 컨테이너의 기본 개념부터 시작해 BeanFactory와 ApplicationContext의 차이, 그리고 실무에서 ApplicationContext가 사실상 표준으로 쓰이는 이유까지 차근차근 살펴보겠습니다.
이 글을 읽고 나면 다음 내용을 이해할 수 있을거에요
- Spring Container가 무엇이며 어떤 역할을 하는지
- BeanFactory와 ApplicationContext의 기능과 차이점
- ApplicationContext가 실무에서 기본 컨테이너로 사용되는 이유
- DI를 이해하기 위해 알아야 할 핵심 구조
Spring Container란?

Spring Container는 스프링 애플리케이션의 중심에서 동작하는 핵심 컴포넌트입니다. 컨테이너는 애플리케이션에서 사용할 객체(Bean)를 생성하고 관리하며, 필요한 의존성을 적절히 연결해줍니다.
컨테이너는 다음과 같은 역할을 수행합니다.
- 스프링 빈(Bean) 생성
- 빈의 라이프사이클 관리
- 빈 간 의존성 주입 처리
- 싱글톤 스코프 관리
즉, 개발자가 직접 객체를 생성하고 의존성을 일일이 연결하지 않아도 되도록 대신 처리해 주는 장치라고 이해할 수 있습니다.
스프링 컨테이너는 크게 두 종류로 나뉩니다.
- BeanFactory
- ApplicationContext
BeanFactory란?
BeanFactory는 스프링 컨테이너의 가장 기본적인 형태로, 필요한 시점에 스프링 빈을 생성하고 제공하는 역할을 담당합니다. 말 그대로 “빈을 만드는 공장” 역할만 수행하는 가장 단순한 컨테이너입니다.
아래는 BeanFactory 인터페이스의 일부입니다.
public interface BeanFactory {
Object getBean(String name) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name);
}
BeanFactory 사용 예시
public class BeanFactoryExample {
public static void main(String[] args) {
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
MyBean bean = (MyBean) factory.getBean("myBean");
bean.foo();
}
}
class MyBean {
public void foo() {
System.out.println("foo");
}
}
BeanFactory는 지연 로딩(lazy-loading) 방식을 사용합니다.
즉, getBean() 메서드를 호출하는 시점에 실제 객체를 생성하기 때문에 초기 로딩 비용을 최소화할 수 있습니다.
하지만 실무에서는 BeanFactory를 직접 사용하는 경우가 거의 없습니다.
기능이 제한적이고, 대부분의 상황에서는 확장된 기능을 제공하는 ApplicationContext가 더 적합하기 때문입니다.
ApplicationContext란?
ApplicationContext는 BeanFactory를 확장한 스프링 컨테이너로, 스프링 애플리케이션을 구성하는 데 필요한 대부분의 기능을 제공합니다. 실무에서 우리가 흔히 “스프링 컨테이너”라고 부를 때도 보통 이 ApplicationContext를 의미합니다.
아래는 ApplicationContext 인터페이스의 일부입니다.
public interface ApplicationContext extends
EnvironmentCapable, ListableBeanFactory,
HierarchicalBeanFactory, MessageSource,
ApplicationEventPublisher, ResourcePatternResolver {
}
ApplicationContext가 제공하는 주요 기능
ApplicationContext는 BeanFactory보다 훨씬 풍부한 기능을 제공합니다.
- 국제화(i18n) 메시지 관리
- 이벤트 발행 및 구독 기능
- 리소스(Resource) 읽기
- 환경 변수(Environment) 관리
@ComponentScan을 통한 자동 빈 등록
이러한 기능 덕분에 복잡한 애플리케이션에서도 유지보수성과 확장성을 확보할 수 있습니다.
ApplicationContext 사용 예시
public class ApplicationContextExample {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
MyBean myBean = context.getBean(MyBean.class);
myBean.foo();
}
}
class MyBean {
public void foo() {
System.out.println("foo");
}
}
국제화(i18n) 메시지 사용 예시
public class InternationalizationExample {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MessageSource messages = (MessageSource) context;
String greeting = messages.getMessage("greeting", null, "Default Greeting", Locale.ENGLISH);
System.out.println(greeting);
}
}
BeanFactory vs ApplicationContext 비교
두 컨테이너의 차이는 아래 표로 정리할 수 있습니다.
| 특징 | BeanFactory | ApplicationContext |
| 로딩 방식 | 지연 로딩(Lazy Loading) | 즉시 로딩(Eager Loading) |
| 빈 관리 기능 | 기본 기능만 제공 | 라이프사이클, 후처리, 자동 등록 등 고급 기능 포함 |
| 국제화(i18n) | 지원하지 않음 | 지원 |
| 이벤트 시스템 | 지원하지 않음 | 지원 |
| 실무 활용도 | 거의 사용하지 않음 |
정리하면, ApplicationContext는 BeanFactory의 상위 호환에 해당합니다.
대부분의 스프링 애플리케이션에서는 ApplicationContext가 제공하는 확장 기능이 필수적이기 때문에, 실무에서는 사실상 ApplicationContext만 사용한다고 볼 수 있습니다.
이번 글에서는 스프링 컨테이너의 역할과 구조를 간단히 살펴보았습니다.
다음 글에서는 스프링이 이러한 구조를 바탕으로 DI(의존성 주입)를 실제로 어떻게 처리하는지 더 깊이 있게 알아보겠습니다.
'Backend > Spring 🌱' 카테고리의 다른 글
| Redis 캐싱으로 API 성능 개선하기 (0) | 2024.04.01 |
|---|---|
| Spring SSE와 Redis Pub/Sub으로 구현하는 실시간 알림 (다중 서버 환경까지 스케일링하기) (0) | 2024.03.19 |
| Spring MVC에서 HandlerMapping과 HandlerAdapter를 나눈 이유 (0) | 2024.02.07 |
| 이벤트 기반으로 파일 업로드 기능 구현하기 (0) | 2024.02.07 |
| 전략 패턴으로 확장성 있게 소셜 로그인 설계하기 (0) | 2024.02.07 |
안녕하세요, 저는 주니어 개발자 박석희 입니다. 언제든 하단 연락처로 연락주세요 😆