
Spring Container & Bean - ApplicationContext 와 BeanFactory
스프링 컨테이너의 생성 과정과 스프링 빈 조회 방법 완벽 가이드
Carefreelife98
4분 소요
스프링 컨테이너
기존: 개발자가 직접 자바코드로 모든 것을 함. 스프링 사용: 스프링 컨테이너에 객체를 스프링 빈으로 등록하고, 스프링 컨테이너에서 스프링 빈을 찾아 사용하도록 변경되었다.
Application Context 를 스프링 컨테이너라고 함.
- 기존에는 AppConfig 등을 사용해서 직접 객체를 생성하고 DI(Dependency Injection)를 함
- 스프링에서는 구성 정보 설정을 스프링 컨테이너를 통해서 사용
- 스프링 컨테이너는
@Configuration이 붙은 구성 클래스를 설정 정보로 사용@Bean이라 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록- 이렇게 스프링 컨테이너에 등록된 객체를 Spring Bean 이라고 함
- 스프링 빈은
@Bean이 붙은 메서드의 명을 스프링 빈의 이름으로 사용 applicationContext.getBean("빈 이름", 반환 클래스)를 통해 스프링 빈을 찾을 수 있다
ApplicationContext
- ApplicationContext 는 Interface 이다.
- 스프링 컨테이너의 생성 방식 두 가지:
- XML
- Annotation 기반의 JAVA 설정 클래스
Annotation 기반의 JAVA 설정 클래스를 통한 생성
1ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class)- AnnotationConfigApplicationContext() 는 ApplicationContext 인터페이스의 구현체
스프링 컨테이너의 생성 과정
1. 스프링 컨테이너 생성

new AnnotationConfigApplicationContext(설정/구성 클래스)- 위 구현체 생성 시 스프링 컨테이너가 생성됨- 스프링 컨테이너 내부에는 스프링 빈 저장소가 존재 (Key-Value 형태)
- Key: 스프링 빈의 이름
- Value: 스프링 빈 객체
- 스프링 컨테이너는 생성 시에 사용한 설정/구성 클래스의 정보를 보고 스프링 빈 등록
2. 스프링 빈 등록

스프링 컨테이너는 설정 정보 클래스에서 @Bean Annotation이 붙은 메서드들을 모두 찾아 스프링 빈 저장소에 등록한다.
- Key: 메서드 이름 (옵션 name="" 을 사용해 직접 부여도 가능)
- 스프링 빈 이름은 유일한 이름을 부여해야 한다
- Value: 메서드 리턴 값 (객체)
3. 스프링 빈 의존관계 설정

- 스프링 컨테이너는 등록된 설정 정보를 사용해서 의존 관계를 주입한다 (Dependency Injection)
- 객체 인스턴스 간 의존관계를 동적으로 주입
스프링 빈 조회
모든 빈 출력하기
1AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);2
3@Test4@DisplayName("모든 빈 출력하기")5void findAllBean() {6 String[] beanDefinitionNames = ac.getBeanDefinitionNames();7
8 for (String beanDefinitionName : beanDefinitionNames) {9 Object bean = ac.getBean(beanDefinitionName);10 System.out.println("name = " + beanDefinitionName + " Object = " + bean);11 }12}
ac.getBeanDefinitionNames(): 스프링에 등록된 모든 빈 이름을 조회ac.getBean(): 빈 이름으로 빈 객체(인스턴스)를 조회
애플리케이션 빈 출력하기
1@Test2@DisplayName("애플리케이션 빈 출력하기")3void findApplicationBean() {4 String[] beanDefinitionNames = ac.getBeanDefinitionNames();5
6 for (String beanDefinitionName : beanDefinitionNames) {7 BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);8
9 if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {10 Object bean = ac.getBean(beanDefinitionName);11 System.out.println("name = " + beanDefinitionName + " Object = " + bean);12 }13 }14}
- ROLE_APPLICATION: 일반적으로 개발자가 개발을 위해 정의한 빈
- ROLE_INFRASTRUCTURE: 스프링이 내부에서 사용하는 빈
스프링 빈 조회 (기본)
1// 방법 12Object bean = ac.getBean(빈 이름, 타입);3
4// 방법 25Object bean = ac.getBean(타입);6
7// 조회 대상 스프링 빈이 없으면 예외 발생8// NoSuchBeanDefinitionException: No bean named '~' available스프링 빈 조회 실패 - NoUniqueBeanDefinitionException
동일한 타입의 빈이 둘 이상 존재할 때 타입으로만 조회하면 예외가 발생한다.
해결 방법: 빈 이름을 지정하여 조회
1MemberRepository memberRepository = ac.getBean("memberRepository1", MemberRepository.class);특정 타입의 스프링 빈 전체 조회하기
1@Test2@DisplayName("특정 타입을 가진 모든 빈 조회하기")3void findAllBeanByType() {4 Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class);5 for (String key : beansOfType.keySet()) {6 System.out.println("key = " + key + " value = " + beansOfType.get(key));7 }8
9 assertThat(beansOfType.size()).isEqualTo(2);10}
BeanFactory
- 스프링 컨테이너의 최상위 인터페이스
- 스프링 빈을 관리하고 조회하는 역할을 담당
getBean()메서드를 제공
ApplicationContext
- BeanFactory 기능을 모두 상속받아서 제공
- 애플리케이션 개발 시 빈 관리/조회 기능 외에 추가적인 부가 기능 제공
ApplicationContext 가 제공하는 부가기능

- 메시지 소스를 활용한 국제화 기능: 한국에서 접근 시 한국어, 영미권에서 접근 시 영어 출력
- 환경 변수: Local, Dev, Release 등의 환경을 구분하여 처리
- Application Event: 이벤트를 발행하고 구독하는 모델을 편리하게 지원
- 편리한 리소스 조회: File, Classpath, External 등의 Resource 들을 편리하게 조회
정리
- ApplicationContext는 BeanFactory의 기능을 상속받는다
- ApplicationContext는 빈 관리기능 + 편리한 부가 기능을 제공한다
- BeanFactory를 직접 사용할 일은 거의 없다
- BeanFactory / ApplicationContext를 스프링 컨테이너라 한다