[spring기본]4. 스프링 컨테이너와 스프링 빈-스프링 빈 조회하기

이건회·2022년 8월 29일
0

springbasic

목록 보기
5/14

스프링 컨테이너 생성과정

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
  • ApplicationContext 인터페이스는 스프링 컨테이너다. 고로 다형성이 적용된다(인터페이스). 즉 ApplicationContext의 구현체가 AnnotationConfigApplicationContext인 것이다.

new AnnotationConfigApplicationContext(AppConfig.class);
  • 위 코드가 AppConfig의 정보를 주며 컨테이너가 만들어진다.
  • 키는 빈 이름, 값은 빈 객체 형태로 저장소가 만들어진다.
  • 스프링 컨테이너를 생성할때는 구성 정보를 지정해주는데, AppConfig.class가 그것이다.

  • 이제 스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보를 사용해서 스프링 빈을 등록한다.
  • 빈 이름은 메소드 이름을 사용하지만, 임의로 부여할 수도 있다( @Bean(name="memberService2"))
  • 빈의 이름은 항상 다르게 부여해야 한다.(딕셔너리 형태니까 당연하다...)


  • 이제 Appconfig의 의존관계 정보를 파악해 그것을 토대로 스프링이 의존관계를 설정한다.
  • 스프링 컨테이너가 AppConfig를 참고해 의존관계 주입(DI)을 하는 것이다.
  • 사실 원래는 스프링 빈을 생성하고 의존관계 주입 단계가 나누어 있지만, 여기서는 스프링 빈 등록과 함께 의존관계 설정이 된다. 이것은 그냥 이해를 돕기 위한 코드다.

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

  • 이제 빈이 잘 등록 됐는지 테스트코드를 짜보자

  • getBeanDefinitionNames()를 통해 모든 빈 이름을 꺼낼 수 있다.
  • 빈 이름을 통해 차례로 getBean을 사용해 조회를 한다.
  • 스프링 컨테이너의 모든 빈들이 출력된다.

  • getBeanDefinition() 는 빈의 메타 데이터를 꺼내온다.
  • getRole() 은 빈의 정의 된 여러가지 역할 중 어떤 역할인지를 출력하는데, 이 역할 중 ROLE_APPLICATION은 스프링 내부가 아닌 애플리케이션 개발을 위해 등록한 빈을 의미한다.
  • 이제 기본 빈을 제외하고 애플리케이션 개발을 위해 등록된 빈만 출력된다.

중간정리

  • ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈 이름을 조회한다.
  • ac.getBean() : 빈 이름으로 빈 객체(인스턴스)를 조회한다.
  • 스프링이 내부에서 사용하는 빈은 제외하고, 내가 등록한 빈만 출력하려면 스프링이 내부에서 사용하는 빈을 getRole() 로 구분한다.
  • ROLE_APPLICATION : 일반적으로 사용자가 정의한 빈
  • ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈

스프링 빈 조회 - 기본

  • 기본적으로 스프링 빈을 찾을때는

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

  • ac.getBean(타입) 을 사용한다

  • 그러나 만약 조회 대상 빈이 없으면 예외가 발생한다.
    -> NoSuchBeanDefinitionException: No bean named 'xxxxx' available

  • 테스트코드를 통해 시도해 보자

  • AssertThat의 isInstanceOf()를 사용하면 어떤 특정 객체의 인스턴스가 맞는지 확인할 수 있다.
  • 빈 이름을 통해 조회했다.

  • 이제 이름 없이 타입으로만 조회할 수도 있다.

  • 구체 타입으로 조회할 수도 있다.
  • MemberServiceImpl 을 통해 조회할 수도 있다.
  • 그러나 항상 역할에 의존하도록 해야 하므로 구현보다는 역할을 통해 조회하자.

  • 실패 테스트를 해보자. 없는 이름의 빈을 조회하면 예외가 난다.
  • NoSuchBeanDefinitionException: No bean named 'XXXXXX' available

  • 그러나 이것보단 예상되는 예외를 지정하고 이 예외가 터지면 성공하도록 테스트를 짜는 것이 좋다.
  • 람다식(->)으로 작성한다 -> 오른쪽의 로직을 실행하면 왼쪽의 예외가 터져야 한다는 것이다.

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

  • 타입으로 스프링 빈 조회시 같은 타입의 빈이 둘 이상이면 오류가 발생하는데, 이때는 빈 이름을 지정하자.

  • 테스트 코드 안에 임의로 Config을 만들어서 돌려보자.
  • getBean(타입)을 통해 빈을 조회하려 했지만 같은 타입이 두개 이상이라 예외(NoUniqueBeanDefinitionException)가 난다.

  • 실패 테스트를 만들어준다.

  • 이제 빈 이름을 지정해 같은 타입의 빈이 둘 이상 발생해도 예외가 나오지 않도록 테스트한다.

  • 이제 특정 타입을 조회할때 둘 이상이 발생해도 모두 조회할 수 있도록 테스트하자
  • .getBeansOfType() 메소드를 사용하면 빈들이 키-값 형태의 Map 형태로 반환된다.
  • 중복되는 빈이 2개므로 .getBeansOfType의 size가 2이면 성공하는 것이다.

스프링 빈 조회 - 상속 관계

  • 빈을 조회할 때, 부모 타입으로 조회하면 자식 타입 즉 자식 빈들이 다 끌려나온다(함께 조회된다).
  • 그래서 모든 자바 객체의 최고 부모인 Object 타입으로 조회하면 모든 스프링 빈을 조회한다.

  • 먼저 부모 타입으로 조회할 때 자식이 둘 이상이라 중복 오류가 나는 테스트다.

  • 이제 부모 타입으로 조회하지만 자식으로 딸려온 "rateDiscountPolicy"로 빈 이름을 지정해 오류를 해결한다.

  • 이제는 부모 타입이 아닌 특정 하위 타입으로 조회하여 오류가 나지 않는다.

  • 이제 부모 타입으로 모두 조회한다. 이전처럼 getBeansOfType을 사용해 Map 형태로 반환한다.

  • 역시 부모 타입으로 모두 조회하지만, 이제 Object 타입으로 꺼낸 경우다. Object가 자바 객체의 최고 부모이므로, 스프링 내부 빈 비롯 전부 다 꺼내진다.
profile
하마드

0개의 댓글