프로그래밍/Spring

[Spring] Section 4. 스프링 컨테이너와 스프링 빈

타나즈 2024. 6. 6. 22:33
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

ApplicationContext를 스프링 컨테이너라 한다.

ApplicationContext는 인터페이스이다.

 

컨테이너에 있는 모든 빈을 조회해보자.

public class ApplicationContextInfoTest {
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    @Test
    @DisplayName("모든 빈 출력")
    void findAllBean() {
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println(beanDefinitionName + "  object =" + bean);
        }
    }
    @Test
    @DisplayName("어플리케이션 빈 출력")
    void findApplicationBean() {
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

            if(beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
                Object bean = ac.getBean(beanDefinitionName);
                System.out.println(beanDefinitionName + "  object =" + bean);
            }
        }
    }
}

ac.getBean(beanDefinitionName): 빈 이름으로 빈 객체 조회 (Object 타입의 bean)

* ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈 이름 조회

 

getRole() 로 구분

ROLE_APPLICATION : 일반적으로 사용자가 정의한 빈

ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈

 

타입으로조회

ac.getBeansOfType(): 해당 타입의 모든 빈 조회
 타입으로 조회 시, 같은 타입의 스프링 빈이 둘 이상이면 오류 발생 => 빈 이름 지정하기

 

상속 관계
부모 타입으로 조회 => 자식 타입도 함께 조회
ex) Object 타입(모든 자바 객체의 최고 부모)으로 조회 => 모든 스프링 빈 조회

 

모든 자바 객체의 최고 부모 타입인 Object타입으로 스프링 빈을 조회하면, 모든 스프링 빈을 조회한다.

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

class ApplicationContextExtendsFindTest{
	
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
    
    @Test
    @DisplayName("부모 타입 조회시, 자식이 둘 이상 있으면 중복 오류 발생")
    void findBeanByParentTypeDuplicate(){
    	assertThrows(NoUniqueBeanDefinitionException.class, () -> ac.getBean(DiscountPolicy.class));
    }
    
    @Test
    @DisplayName("부모 타입 조회 시, 자식이 둘 이상 있으면 빈 이름을 지정하자")
    void findBeanByParentTypeBeanName(){
    	DiscountPolicy rateDiscountPolicy = ac.getBean("rateDiscountPolicy", DiscountPolicy.class);
        assertThat(rateDiscountPolicy).isInstanceOf(RateDiscountPolicy.class);
    }

 

🍘 BeanFactory와 ApplicationContext

BeanFactory
스프링 컨테이너의 최상위 인터페이스
스프링 빈을 관리하고 조회하는 역할 담당
getBean() 제공

ApplicationContext
BeanFactory 기능 모두 상속받아 제공
빈 관리 기능 + 여러 부가 기능

부가 기능 예시)

  • 메시지소스 활용한 국제화 기능
  • 환경변수 (로컬, 개발, 운영 등 구분하여 처리)
  • 애플리케이션 이벤트 (이벤트를 발행, 구독하는 모델을 편리하게 지원)
  • 편리한 리소스 조회 (파일, 클래스패스, 외부 등에서 리소스를 편리하게 조회)

🍘다양한 설정 형식 지원 - 자바 코드, XML ..

스프링 컨테이너는 다양한 형식의 설정 정보를 받아들일 수 있게 유연하게 설계되어 있음
ex) 자바 코드, XML, Groovy 등등
자바 코드(애노태이션 기반) => AnnotationConfigApplicationContext 클래스
XML => GenericXmlApplicationContext 클래스

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

BeanDefinition 추상화 => 스프링의 다양한 설정 형식 지원

역할과 구현을 개념적으로 나눈 것

스프링 컨테이너는 자바 코드인지, XML인지 몰라도 됨, BeanDefinition만 알면 됨

BeanDefinition을 빈 설정 메타정보라고 추상화함
각각 @Bean, 당 하나씩 메타 정보 생성

 

출처 : 김영한 스프링 핵심 원리