스프링 컨테이너와 스프링 빈이란?

무삭이의 개발일지·2023년 3월 4일
0
post-thumbnail

inflearn Spring 핵심원리 -기본 김영한 강사님 자료 참고

스프링 컨테이너

//스프링 컨테이너 생성
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(AppConfig.class);

  • ApplicationContext를 스프링 컨테이너라 한다.
  • ApplicationContext는 인터페이스다.
  • AnnoationConfigApplicationContext는 ApplicationContext 인터페이스의 구현체이다.

보통 스프링 컨테이너를 부를 때 BeanFactory, ApplicationContext로 구분해서 이야기한다.
BeanFactory를 직접 사용하는 경우는 거의 없어서 ApplicationContext를 스프링 컨테이너라 한다.

스프링 컨테이너 생성 과정

  • new AnnotationConfigApplicationContext(Appconfig.class)
    • 스프링 컨테이너를 생성할 때 구성 정보를 지정 해줘야한다.
    • AppConfig.class를 구성 정보로 지정했기 때문에 파라미터에 들어간다.

  • 스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보를 사용해서 스프링 빈을 등록한다.
  • 빈 이름은 메서드 이름으로 사용한다. 직접 부여도 가능하지만 메서드 이름은 Default

  • 스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입(DI)한다.

빈이 잘 저장 되어있는지 확인해보자.

AnnotationConfigApplicationContext ac =
new AnnotationConfigApplicationContext(AppConfig.class);

void findBeanByName(){
MemberService memberService = ac.getBean("memberService", MemberService.class);
assertThat(memberService).isInstanceOf(MemberServiceImpl.class);

먼저 스프링 컨테이너(ac)를 생성 하고 설정 정보(AppConfig)를 지정해줬다.
빈 이름으로 조회를 해봤다. "memberService"메서드 이름, 곧 빈 이름.
MemberService.class 반환 타입..!!

빈 이름 없이 타입으로도 조회가 가능하며, 구체 타입으로만 조회도 가능하지만 구체 타입으로만 조회는 권장하지 않는다.

void findBeanByNameX(){
assertThrows(NoSuchBeanDefinitionException.class, () ->
ac.getBean("xxxx", MemberService.class));
}

빈이 존재 하지 않는다면 NoSuchBeanDefinitionException이 발생한다.
ac.getBean("xxxx", MemberService.class가 존재 하지 않는다면 NoSuchBeanDefinitionException.class가 발생한다는 뜻의 람다식으로 빈 조회가 없을시 테스트 코드를 작성한다.

void findAllBeanByType(){
    Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class);
    for (String key : beansOfType.keySet()) {
        System.out.println("key = " + key + " value = " + beansOfType.get(key));
    }
    System.out.println("beansOfType = " + beansOfType);
    assertThat(beansOfType.size()).isEqualTo(2);
}

특정 타입을 모두 조회할 때는 ac.getBeansOfType를 사용한다.

void findBeanByParentTypeDuplicate(){

// DiscountPolicy bean = ac.getBean(DiscountPolicy.class);
Assertions.assertThrows(NoUniqueBeanDefinitionException.class, () ->
ac.getBean(DiscountPolicy.class));
}

부모 타입으로 조회시, 자식이 둘 이상 있으면, 중복 오류가 발생한다. 부모 타입 조회시 자식이 다 딸려 나오기 때문에 빈 이름을 지정해서 찾거나 getBeansOfType으로 부모 타입 조회 하여 확인 해야한다.

BeanFactory와 ApplicationContext

BeanFactory

  • 스프링 컨테이너의 최상위 인터페이스다.
  • 스프링 빈을 관리하고 조회하는 역할을 담당한다.
  • getBean()을 제공한다.
  • 지금까지 사용한 대부분의 기능들은 BeanFactory가 제공하는 기능이었다.

ApplicationContext

  • BeanFactory기능을 모두 상속받아서 제공한다.
  • BeanFactory와 차이는? -> 애플리케이션을 개발할 때는 빈을 관리하고 조회하는 기능은 물론이고, 수 많은 부가 기능이 필요하다.

BeanFactory를 직접 사용할 일은 거의 없다. 부가 기능이 포함된 ApplicationContext를 사용한다.
BeanFactory나 ApplicationContext를 스프링 컨테이너라 한다.

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

스프링은 다양한 설정 형식을 지원 하는데 그 중심에는 BeanDefinition이라는 추상화가 있다.
스프링 컨테이너느 자바 코드인지, XML인지 모른다. 오직 BeanDefinition만 알면 된다.
BeanDefinition을 빈 설정 메타정보라고 한다.
스프링 컨테이너는 이러한 메타 정보를 기반으로 스프링 빈을 생성한다.

스프링 컨테이너는 단지 BeanDefinition을 의존할 뿐, 어떤 설정이 들어오는지는 모른다.

AnnotationConfigApplicationContext는 AnnotatedBeanDefinitionReader를 통해 설정 정보인 AppConfig.class를 읽는다. 설정 정보를 읽고 나서 BeanDefinition 빈 메타 정보를 생성한다.

스프링이 다양한 형태의 설정 정보를 BeanDefinition으로 추상화해서 사용한다..!!!

profile
No. Try not. Do or Do not. There is no try.

0개의 댓글