2 분 소요


1. 스프링 컨테이너와 스프링 빈 정리

2. 스프링 컨테이너 생성

스프링 컨테이너는 애플리케이션의 설정 정보를 바탕으로 스프링 빈을 관리하고 의존관계를 주입하는 역할을 한다.

// 스프링 컨테이너 생성
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
  • ApplicationContext는 스프링 컨테이너의 인터페이스이다.
  • 자바 설정 클래스를 기반으로 스프링 컨테이너가 생성된다.


3. 스프링 컨테이너 생성 과정

  1. 스프링 컨테이너 생성
    • 설정 정보를 제공하여 컨테이너를 생성한다.
  2. 스프링 빈 등록
    • 설정 클래스 정보를 바탕으로 스프링 빈을 등록한다.
    • 빈 이름은 기본적으로 메서드 이름을 사용하지만, 직접 지정할 수도 있다.
  3. 스프링 빈 의존관계 설정 - 준비
    • 빈들 간의 의존관계를 설정한다.
  4. 스프링 빈 의존관계 설정 - 완료
    • 의존관계가 모두 주입되며 준비가 완료된다.


4. 컨테이너에 등록된 모든 빈 조회

스프링 컨테이너에 등록된 빈을 출력하여 확인할 수 있다.

String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
    Object bean = applicationContext.getBean(name);
    System.out.println("name=" + name + " object=" + bean);
}
  • getBeanDefinitionNames(): 모든 빈의 이름을 반환한다.
  • getBean(name): 빈 이름으로 객체를 조회한다.


5. 애플리케이션 빈만 출력하기

스프링 내부에서 사용하는 빈을 제외하고, 직접 등록한 애플리케이션 빈만 출력할 수 있다.

for (String name : beanDefinitionNames) {
    BeanDefinition beanDefinition = applicationContext.getBeanDefinition(name);
    if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
        Object bean = applicationContext.getBean(name);
        System.out.println("name=" + name + " object=" + bean);
    }
}


6. 스프링 빈 조회 - 기본

스프링 컨테이너에서 빈을 조회하는 기본 방법은 다음과 같다:

// 빈 이름과 타입으로 조회
MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
  • 이름과 타입을 함께 지정하면 정확히 원하는 빈을 조회할 수 있다.
  • 타입만으로도 조회 가능하지만, 중복된 타입이 있을 경우 오류가 발생할 수 있다.

예제 코드

@Test
@DisplayName("빈 이름으로 조회")
void findBeanByName() {
    MemberService memberService = ac.getBean("memberService", MemberService.class);
    assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}


7. 스프링 빈 조회 - 동일한 타입이 둘 이상

  • 같은 타입의 스프링 빈이 둘 이상이면 오류가 발생한다.
    • 이때는 빈 이름을 명시하거나, 모든 빈을 조회하는 방법을 사용한다.
Map<String, MemberRepository> beansOfType = applicationContext.getBeansOfType(MemberRepository.class);
for (String key : beansOfType.keySet()) {
    System.out.println("key = " + key + " value = " + beansOfType.get(key));
}


8. 스프링 빈 조회 - 상속 관계

부모 타입으로 조회하면 자식 타입도 함께 조회된다.

@Test
@DisplayName("부모 타입으로 조회시, 자식이 둘 이상 있으면, 빈 이름을 지정")
void findBeanByParentType() {
    DiscountPolicy discountPolicy = ac.getBean("rateDiscountPolicy", DiscountPolicy.class);
    assertThat(discountPolicy).isInstanceOf(RateDiscountPolicy.class);
}


9. BeanFactory와 ApplicationContext

  • BeanFactory: 스프링 컨테이너의 최상위 인터페이스로, 빈 관리와 조회 기능을 제공한다.
  • ApplicationContext: BeanFactory의 기능을 모두 상속받고, 추가적인 부가 기능을 제공한다.
    • 메시지소스를 활용한 국제화 기능
    • 환경 변수 및 애플리케이션 이벤트 관리
    • 편리한 리소스 조회 기능 등


10. 다양한 설정 형식 지원

스프링 컨테이너는 다양한 설정 형식을 지원한다:

  • 자바 코드 기반 설정: AnnotationConfigApplicationContext
  • XML 기반 설정: GenericXmlApplicationContext

예제:

ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
MemberService memberService = ac.getBean("memberService", MemberService.class);
assertThat(memberService).isInstanceOf(MemberService.class);

XML 설정 예시 (appConfig.xml):

<beans xmlns="http://www.springframework.org/schema/beans">
    <bean id="memberService" class="hello.core.member.MemberServiceImpl">
        <constructor-arg name="memberRepository" ref="memberRepository"/>
    </bean>
    <bean id="memberRepository" class="hello.core.member.MemoryMemberRepository"/>
    <bean id="orderService" class="hello.core.order.OrderServiceImpl">
        <constructor-arg name="memberRepository" ref="memberRepository"/>
        <constructor-arg name="discountPolicy" ref="discountPolicy"/>
    </bean>
    <bean id="discountPolicy" class="hello.core.discount.RateDiscountPolicy"/>
</beans>


11. BeanDefinition

스프링은 다양한 설정 형식을 BeanDefinition으로 추상화하여 사용한다.

  • 자바 코드나 XML 설정을 읽어 BeanDefinition을 생성한다.

예제:

@Test
@DisplayName("빈 설정 메타정보 확인")
void findApplicationBean() {
    String[] beanDefinitionNames = ac.getBeanDefinitionNames();
    for (String name : beanDefinitionNames) {
        BeanDefinition beanDefinition = ac.getBeanDefinition(name);
        if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
            System.out.println("beanDefinitionName=" + name + " beanDefinition=" + beanDefinition);
        }
    }
}


12. 정리

  • 스프링 컨테이너는 설정 정보를 바탕으로 스프링 빈을 관리하고 의존관계를 설정한다.
  • ApplicationContext는 빈 관리 기능과 함께 다양한 부가 기능을 제공한다.
  • 다양한 설정 형식을 BeanDefinition으로 추상화하여 유연하게 지원한다.


카테고리:

업데이트:

댓글남기기