Search
🌱

[스프링] 스프링 컨테이너와 스프링 빈

Tags
Study
Spring
Last edited time
2025/03/30 08:50
2 more properties

1. 서론

스프링 프레임워크의 핵심은 스프링 컨테이너와 그 안에서 관리되는 스프링 빈입니다. 이 포스팅에서는 스프링 컨테이너의 생성 과정부터 빈 조회 방법, 그리고 컨테이너가 다양한 설정 형식을 지원하는 원리인 BeanDefinition까지 자세히 알아보겠습니다.

2. 스프링 컨테이너 생성과 빈 등록 과정

2.1. 개요

스프링 컨테이너는 ApplicationContext 인터페이스를 구현한 클래스의 인스턴스입니다. 스프링 컨테이너를 생성하는 가장 일반적인 방법은 다음과 같습니다
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
Java
복사
여기서 AnnotationConfigApplicationContextApplicationContext 인터페이스의 구현체로, Java 기반 설정 클래스를 사용하여 스프링 컨테이너를 생성합니다.

2.2. 스프링 컨테이너 생성 단계

1.
스프링 컨테이너 생성
구성 정보(AppConfig.class)를 지정하여 컨테이너 생성
2.
스프링 빈 등록
구성 정보를 바탕으로 빈 등록 (빈 이름은 메서드 이름 기본 사용)
3.
스프링 빈 의존관계 설정 준비
의존관계 주입을 위한 준비 단계
4.
스프링 빈 의존관계 설정 완료
설정 정보를 참고하여 의존관계 주입(DI) 완료

3. 스프링 빈 조회 방법

스프링 컨테이너에서 빈을 조회하는 다양한 방법이 있습니다
// ApplicationContext & AppConfig 설정은 선행으로 필요. 소스코드 참고 ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
TypeScript
복사

3.1. 기본 조회 방법

// 빈 이름과 타입으로 조회 MemberService memberService = ac.getBean("memberService", MemberService.class); // 타입으로만 조회 MemberService memberService = ac.getBean(MemberService.class); // 구체 타입으로 조회 (유연성 감소) MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
Java
복사

3.2. 동일 타입이 여러 개일 경우

// 모든 빈 조회 Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class); // 특정 빈 이름으로 조회 MemberRepository memberRepository = ac.getBean("memberRepository1", MemberRepository.class);
Java
복사

3.3. 상속 관계

부모 타입으로 조회하면 자식 타입도 함께 조회됩니다. 따라서 Object 타입으로 조회하면 모든 스프링 빈이 조회됩니다.
// 부모 타입으로 조회하면 자식 타입도 함께 조회됨 Map<String, DiscountPolicy> beansOfType = ac.getBeansOfType(DiscountPolicy.class);
Java
복사

4. BeanFactory와 ApplicationContext

4.1. BeanFactory

스프링 컨테이너의 최상위 인터페이스
스프링 빈 관리와 조회를 담당
getBean() 메소드 제공

4.2. ApplicationContext

BeanFactory를 상속받은 인터페이스
빈 관리 기능 + 다양한 부가 기능 제공

4.3. ApplicationContext가 제공하는 부가 기능

메시지소스 활용한 국제화 기능: 다국어 처리
환경변수 관리: 로컬, 개발, 운영 환경 구분
애플리케이션 이벤트: 이벤트 발행/구독 모델 지원
편리한 리소스 조회: 파일, 클래스패스, 외부 등의 리소스 조회

5. 다양한 설정 형식 지원

스프링 컨테이너는 다양한 형식의 설정 정보를 처리할 수 있습니다

5.1. Java 코드 기반 설정

ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
Java
복사

5.2. XML 기반 설정

ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
Java
복사
// XML 예시 <beans> <bean id="memberService" class="hello.core.member.MemberServiceImpl"> <constructor-arg name="memberRepository" ref="memberRepository" /> </bean> <bean id="memberRepository" class="hello.core.member.MemoryMemberRepository" /> </beans>
XML
복사

6. 스프링 빈 설정 메타 정보 - BeanDefinition

스프링이 다양한 설정 형식을 지원하는 핵심에는 BeanDefinition이라는 추상화가 있습니다. BeanDefinition은 빈 설정에 대한 메타 정보를 담고 있으며, 스프링 컨테이너는 이 메타 정보를 기반으로 빈을 생성합니다.

6.1. BeanDefinition의 역할

스프링 컨테이너가 다양한 설정 형식(Java, XML 등)을 처리할 수 있게 해주는 추상화
@Bean 또는 <bean> 정의마다 하나의 BeanDefinition 메타 정보 생성
설정 형식과 상관없이 일관된 방식으로 빈 관리 가능

6.2. BeanDefinition 주요 정보

BeanClassName: 생성할 빈의 클래스명
factoryBeanName: 팩토리 빈 사용 시 이름 (예: appConfig)
factoryMethodName: 빈 생성 팩토리 메서드 (예: memberService)
Scope: 빈의 스코프 (기본값: 싱글톤)
lazyInit: 지연 초기화 여부
InitMethodName: 초기화 메서드명
DestroyMethodName: 소멸 메서드명
Constructor arguments, Properties: 의존관계 주입에 사용
graph TD
    A[스프링 컨테이너] --> B[BeanDefinition]
    C[XML 설정] --> D[XmlBeanDefinitionReader] --> B
    E[자바 코드 설정] --> F[AnnotatedBeanDefinitionReader] --> B
    G[기타 형식 설정] --> H[XXXBeanDefinitionReader] --> B
Mermaid
복사

5.3. BeanDefinition 계층 구조

graph TD
    A[ApplicationContext] --> 
    B1[AnnotationConfigApplicationContext]
    A --> B2[GenericXmlApplicationContext]
    A --> B3[XXXApplicationContext]

    B1 --> C1[AnnotatedBeanDefinitionReader]
    B2 --> C2[XmlBeanDefinitionReader]
    B3 --> C3[XXXBeanDefinitionReader]

    C1 --> D1(설정 정보 읽기)
    C2 --> D1
    C3 --> D1

    D1 --> E[BeanDefinition]
    E --> F(빈 메타 설정)
    F --> G[스프링 빈]
Mermaid
복사

7. BeanDefinition의 핵심 이해

스프링은 BeanDefinition이라는 추상화를 통해 다양한 설정 형식을 지원합니다. 설정이 어떤 형식(Java, XML 등)으로 되어 있든, 최종적으로는 BeanDefinition으로 변환되어 스프링 컨테이너에 등록됩니다.
Java 코드 기반 설정에서는 AnnotatedBeanDefinitionReaderAppConfig.class를 읽어 BeanDefinition 생성
XML 기반 설정에서는 XmlBeanDefinitionReaderappConfig.xml을 읽어 BeanDefinition 생성
새로운 형식의 설정이 추가되면, 해당 형식에 맞는 XXXBeanDefinitionReader를 구현하여 BeanDefinition 생성
이러한 추상화 계층 덕분에 스프링은 설정 형식에 구애받지 않고 일관된 방식으로 빈을 관리할 수 있습니다.

8. 결론

스프링 컨테이너와 빈의 원리를 이해하면 스프링 프레임워크를 더 효과적으로 활용할 수 있습니다.
특히 BeanDefinition이라는 추상화 개념은 스프링의 유연성과 확장성의 핵심이며, 다양한 설정 방식을 지원하는 원리가 됩니다.
실무에서 BeanDefinition을 직접 다룰 일은 거의 없지만, 스프링의 내부 동작 원리를 이해하는 데 중요한 개념입니다.
참고 소스코드
b1d4497b1212e07bb97584c24d7746162d31e3b2
commit