minghxx.blog
  • [Spring] 스프링 핵심 원리 기본편 4) 스프링 컨테이너와 스프링 빈
    2023년 10월 21일 15시 53분 17초에 업로드 된 글입니다.
    작성자: 민발자
    728x90

    스프링 핵심 원리 - 기본편

    Session 4 스프링 컨테이너와 스프링 빈

    1. 스프링 컨테이너 생성

    1) 스프링 컨테이너 생성

    ApplicationContext appllicationContext = new AnnotaionConfigApplicationContext(AppConfig.class);

    ApplicationContext : 스프링 컨테이너라고 하고 인터페이스임

    AppConfig에 @Configuration 붙여서 만든 것이 애노테이션 기반의 설정 클래스를 만들어 스프링 컨테이너를 만든 것

     

    2) 스프링 컨테이너 생성과정

    스프링 컨테이너 설정

    new AnnotationConfigApplicationContext(AppConfig.class)로 스프링 컨테이너 생성

    매개변수로 구성정보를 지정해줌

    스프링 빈 등록

    스프링 컨테이너는 매개변수로 받은 구성 정보를 이용해 스프링 빈을 등록

    빈 이름은 항상 다른 이름을 부여해야한다(같은 이름을 부여하면 빈이 무시되거나 기존 빈을 덮어버리거나 설정에 따라 오류 발생)

    구성 정보를 참고해서 의존관계를 주입한다(DI)

     

    ▶ 스프링 빈을 생성하고 의존관계 주입 단계가 나눠져 있음 자세한 내용은 의존관계 자동 주입에서 설명


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

    1) 모든 빈 출력하기

    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
    
    // 스프링에 등록된 모든 빈 정보를 출력
    String[] beanDefinitionNames = ac.getBeanDefinitionNames();
    
    // ac.getBean() 빈 이름으로 빈 객체(인스턴스) 조회
    for (String beanDefinitionName : beanDefinitionNames) {
    	Object bean = ac.getBean(beanDefinitionName);
    }
    
    // ROLE_APPLICATION: 직접 등록한 애플리케이션 빈, 일반적으로 사용자가 정의한 빈
    // ROLE_INFRASTRUCTURE: 스프링이 내부에서 사용하는 빈
    if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
    	Object bean = ac.getBean(beanDefinitionName);
    }

    3. 스프링 빈 조회 - 기본

    1) 빈을 조회하는 가장 기본적인 조회 방법

    ac.getBean(빈이름, 타입);

    ac.getBean(타입);

    조회 대상 스프링 빈이 없으면 예외 발생 NoSuchBeanDefinitionException

    @Test
    @DisplayName("빈 이름으로 조회") void findBeanByName() {
         MemberService memberService = ac.getBean("memberService", MemberService.class);
         assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
         // memberService가 MemberServiceImpl의 인스턴스면 테스트 통과
    }
    @Test
    @DisplayName("구체 타입으로 조회") void findBeanByName2() {
        MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
        assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
    }
    // 구체타입으로 조회하면 변경시 유연성이 떨어진다.
    @Test
    @DisplayName("빈 이름으로 조회X") void findBeanByNameX() {
         Assertions.assertThrows(NoSuchBeanDefinitionException.class, () -> ac.getBean("xxxxx", MemberService.class));
         // xxxxx 이름의 빈이 없으면 예외 발생해서 테스트 성공
    
    }

     


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

    1) 동일한 타입의 빈을 조회

    타입으로 조회시 같은 타입의 스프링 빈이 둘 이상이면 오류 발생(NoUniqueBeanDefinitionException 발생), 이때는 빈 이름으로 조회

    ac.getBeansOfType()을 사용하면 해당 타입의 모든 빈을 조회

    @Test
    @DisplayName("특정 타입을 모두 조회하기") void findAllBeanByType() {
        Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class);
        for (String key : beansOfType.keySet()) {
            System.out.println("key = " + key + " value = " + beansOfType.get(key));
        }
        // 검증
        assertThat(beansOfType.size()).isEqualTo(2);
    }

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

    1) 부모타입으로 조회

    부모타입으로 조회하면 자식타입도 조회, 자바의 모든 객체의 부모인 Object 타입으로 조회하면 모든 스프링 빈을 조회


    6. BeanFactory와 ApplicationContext

    1) BeanFactory

    스프링 컨테이너의 최상위 인터페이스, 스프링 빈을 관리하고 조회하는 역할을 담당

    getBean()을 제공, 지금 사용했던 기능 대부분 빈팩토리가 제공

     

    2)ApplicationContext

    빈팩토리 기능을 모두 상속받아 제공하고 애플리케이션 개발할 때 부가 기능을 제공

     

    ApplicationContext 부가기능

    메시지소스를 활용한 국제화 기능 : 한국 접속-한국어, 영어권 접속-영어

    환경변수 : 로컬, 개발, 운영 등 구분해서 처리

    애플리케이션 이벤트 : 이벤트 발행하고 구독하는 모델을 편리하게 지원

    편리한 리소스 조회 : 파일, 클래스패스, 외부 등에서 리소스 편리하게 조회

     

    3) 정리

    ApplicationContext는 BeanFactory기능 상속 ▶ 빈 관리기능 + 부가기능을 제공

    BeanFactory를 직접 사용할 일을 거의 없음

    BeanFactory나 ApplicationContext를 스프링 컨테이너라고 함


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

    1) 다양한 설정 형식 지원


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

    1) BeanDefinition

    BeanDefinition을 빈 설정 메타정보라고 함

    스프링이 다양한 설정 형식을 지원할 수 있는 이유는 BeanDefinition 추상화 때문

    XML, 자바 코드를 읽어서 BeanDefinition을 생성하고 컨테이너는 BeanDefinition만 알면 된다.

    새로운 형식의 설정 정보가 추가되면 XxxxBeanDefinitionReader를 만들어 BeanDefinition을 생성

    실무에서 직접 사용하는 일은 거의 없음

    728x90
    댓글