스프링 핵심 원리[기본편] - 스프링 컨테이너와 스프링 빈

2022. 12. 27. 11:56·Spring

스프링 컨테이너 생성

//스프링 컨테이너 생성
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
  • ApplicationContext를 스프링 컨테이너(인터페이스)라 한다.
  • AnnotationConfigApplicationContext()은 ApplicationContext의 구현체이다.
  • 직전에 AppConfig 를 사용했던 방식이 애노테이션 기반의 자바 설정 클래스로 스프링 컨테이너를 만든 것이다.

스프링 컨테이너의 생성 과정

1. 스프링 컨테이너 생성

  • 스프링 컨테이너 생성 new AnnotationConfigApplicationContext(AppConfig.class)
  • 스프링 컨테이너를 생성할 때는 구성 정보를 지정해주어야 한다(AppConfig.class)

2. 스프링 빈 등록

  • 스프링 컨테이너는 파라미터(구성정보 , 여기서는 AppConfig)로 넘어온 설정 클래스 정보(@Configuration)를 사용하여 스프링 빈(@Bean) 등록
  • 빈 이름
    • 메서드 이름을 사용(디폴트)
    • @Bean(name="memberService2") 를 통해 직접 부여가능
    • 항상 다른 이름을 사용해야하는것을 명시

3. 스프링 빈 의존관계 설정 - 준비

4. 스프링 빈 의존관계 설정 - 완료

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

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

void findAllBean() {
    String[] beanDefinitionNames = ac.getBeanDefinitionNames();
    for (String beanDefinitionName : beanDefinitionNames) {
        Object bean = ac.getBean(beanDefinitionName);
        System.out.println("name=" + beanDefinitionName + " object=" + bean);
        
        //Role ROLE_APPLICATION: 직접 등록한 애플리케이션 빈
        //Role ROLE_INFRASTRUCTURE: 스프링이 내부에서 사용하는 빈
        if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
        Object bean = ac.getBean(beanDefinitionName);
        	System.out.println("name=" + beanDefinitionName + " object=" + bean);
        }
    }
 }
  • ac.getBeanDefinitionNames() : 스프링 컨테이너의 모든 빈 이름을 조회
  • ac.getBean() : 빈 이름으로 빈 객체 조회
  • getRole() : 내가 등록한 빈 or 스프링에서 등록한 빈을 구분할수 있다.

스프링 빈 조회 - 기본

기본 조회방법

  • ac.getBean(빈이름, 타입)
  • ac.getBean(타입)
class ApplicationContextBasicFindTest {
    AnnotationConfigApplicationContext ac = new
     AnnotationConfigApplicationContext(AppConfig.class);
     @Test
     @DisplayName("빈 이름으로 조회")
     void findBeanByName() {
         MemberService memberService = ac.getBean("memberService",
        MemberService.class);
         assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
     }
     
     @Test
     @DisplayName("이름 없이 타입만으로 조회")
     void findBeanByType() {
         MemberService memberService = ac.getBean(MemberService.class);
         assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
     }
     
     @Test
     @DisplayName("구체 타입으로 조회")
     void findBeanByName2() {
         MemberServiceImpl memberService = ac.getBean("memberService",
        MemberServiceImpl.class);
         assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
     }
}

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

  • NoSuchBeanDefinitionException: No bean named 'xxxxx' available
@Test
@DisplayName("빈 이름으로 조회X")
void findBeanByNameX() {
    //ac.getBean("xxxxx", MemberService.class);
    Assertions.assertThrows(NoSuchBeanDefinitionException.class, () ->
    ac.getBean("xxxxx", MemberService.class));
}

 

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

  • 동일한 타입을 가진 빈이 두가지 이상일때 타입으로만 조회한다면 오류가 발생한다.

중복오류 발생

  • NoUniqueBeanDefinitionException라는 오류 발생
void findBeanByTypeDuplicate() {
	//MemberRepository bean = ac.getBean(MemberRepository.class);
	assertThrows(NoUniqueBeanDefinitionException.class, () ->
	ac.getBean(MemberRepository.class));
}

특정 타입 및 빈 이름 함께 조회

@Test
@DisplayName("타입으로 조회시 같은 타입이 둘 이상 있으면, 빈 이름을 지정하면 된다")
void findBeanByName() {
	MemberRepository memberRepository = ac.getBean("memberRepository1",
	MemberRepository.class);
	assertThat(memberRepository).isInstanceOf(MemberRepository.class);
}

특정 타입을 모두 조회하기

@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));
    }
    System.out.println("beansOfType = " + beansOfType);
    assertThat(beansOfType.size()).isEqualTo(2);
}

스프링 빈 조회 - 상속 관계

  • 스프링 컨테이너에서 빈을 조회할때 부모타입을 조회하면 자식타입도 함께 조회된다.
  • 자바 객체의 최고부모인 Object타입을 조회하면 모든 스프링 빈 조회

BeanFactory와 ApplicationContext

BeanFactory

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

 

ApplicationContext

  • BeanFactory기능을 모두 상속받아 사용
  • 다양한 부가적인 기능 있음

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

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

XML , 자바코드 등 다양한 설정 형식을 지원하게 해주는역할을 BeanDefinition이라는 추상화가 가능하게 해준다.

역할과 구현을 나눈것 -> 인터페이스와 구현체


참고강의

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8

 

728x90
저작자표시 (새창열림)

'Spring' 카테고리의 다른 글

JPA Auditing기능이란?  (0) 2022.12.29
스프링 핵심 원리[기본편] - 의존관계 자동 주입  (0) 2022.12.28
스프링 핵심 원리[기본편] - 컴포넌트 스캔  (0) 2022.12.27
스프링 핵심 원리[기본편] - 싱글톤 컨테이너  (0) 2022.12.27
스프링 핵심 원리[기본편] - 예제만들기 , 객체 지향 원리 적용  (0) 2022.12.27
'Spring' 카테고리의 다른 글
  • 스프링 핵심 원리[기본편] - 의존관계 자동 주입
  • 스프링 핵심 원리[기본편] - 컴포넌트 스캔
  • 스프링 핵심 원리[기본편] - 싱글톤 컨테이너
  • 스프링 핵심 원리[기본편] - 예제만들기 , 객체 지향 원리 적용
study ticket
study ticket
  • study ticket
    혼자하는 공부
    study ticket
  • 전체
    오늘
    어제
    • 개발 (77)
      • 오류 (1)
      • Spring (13)
      • Java (0)
      • Data structure (6)
      • Algorithm (49)
        • 백준 (17)
        • 프로그래머스 (2)
      • 문제풀면서 알게되는것들 끄적 (2)
      • 머신러닝 (4)
        • sklearn (3)
        • pandas (1)
      • 프로젝트 (0)
        • 핏두 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백준1157
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
study ticket
스프링 핵심 원리[기본편] - 스프링 컨테이너와 스프링 빈
상단으로

티스토리툴바