Spring/Spring Core

Spring Bean 조회

민철킹 2021. 3. 9. 18:42

기본

스프링 컨테이너에서 스프링 빈을 찾는 가장 기본적인 조회 방법

  • ac.getBean(빈이름, 타입)
  • ac.getBean(타입)
  • 조회 대상 스프링 빈이 없으면 예외 발생
    • NosuchBeanDefinitionException : No bean named "빈이름" available

1. 빈 이름으로 조회!!

 

Assertions로 검증

  • memberService가 어떤 객체 인스턴스인지?(isInstanceOf)
  • MemberServiceImpl의 인스턴스라면 테스트 통과
  • 테스트 성공

 

2. 이름 없이 타입으로만 조회

  • 테스트 성공!
  • 하지만 같은 타입이 여러 개일 경우에는 곤란해질 수 있음.

 

3. 구체 타입으로 조회

  • 테스트 성공!
  • 스프링 컨테이너에 구현체가 등록만 되어있으면 조회가 됨
  • 스프링 빈에 등록되어 있는 인스턴스 타입(MemberServiceImpl)을 보고 결정을 하기 때문에 꼭 인터페이스가 아니어도 된다.
  • 하지만 구체를 적는 것은 좋지 않음
    • 이것은 역할(interface)에 의존하는 것이 아닌 구현에 의존하기 때문
  • 필요에 따라 사용할 수 도 있음.

 

 

4. 실패 테스트(빈 이름으로 조회하는데 그런 빈이 없을 경우)

 

  • Exception 발생

Junit의 assertThrows로 검증하기

  • assertThrows(해당 Exception명, Logic)
  • NoSuchBeanDefinitionException이라는 예외가 발생하야함.
  • logic은 lambda식 형태로
  • ac.getBean("xxxxx", MemberService.class)를 실행했을 때 해당 Exception이 발생해야 테스트가 성공

테스트 성공!!

 

 


동일한 타입이 둘 이상❗❓❗❓

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

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

 

  • 중복되는 MemberRepository를 Bean에 등록하기위해 미리 만들어두었던 AppConfig가 아닌 클래스 내에서 static으로 새로 Config를 만들어주었다.

  • Exception을 읽어보면 하나의 단독 매칭(single matching)을 기대했는데 동일한 타입의 Bean이 두개있다.라는 오류문이 적혀있다.
  • 갑작스럽긴한데 오류 정말 친절하게 자세하게 알려주는듯 ㅋㅋ

assertThrows로 예외 처리하여 테스트하기

 

  • 해당 로직을 실행하여 NoUniqueBeanDefinitionException이 발생하면 테스트 성공 

테스트 성공!

 

이를 해결하기 위해서는 둘 이상 같은 타입이 있을 때, 빈 이름을 지정하여 조회함.

 

 

해당 타입의 Bean 모두를 꺼내고 싶을 때는 어떻게 해야 할까?

  • 이럴 때는 getBeansOfType을 사용하면 된다.
  • 이 메소드의 return 타입은 Map으로 Key-Value형식으로 반환
  • key - value를 직접 출력시켰고, 맨 마지막에 assertThat을 통하여 반환된 Map의 크기가 2인지 검증한다.
    • 현재 우리가 memberRepository1과 memberRepository2를 Bean에 등록시켰으므로 2여야함.

테스트도 성공하였고, 출력또한 예상결과와 일치함을 확인할 수 있다.

 


상속관계

부모-자식 관계인 상속관계일 때는 어떻게 조회할까?

부모 타입으로 조회하면, 자식 타입도 함께 조회된다. 따라서 모든 자바 객체의 최고 부모인 Object타입으로 조회하면 모든 스프링 빈을 조회할 수 있다.

  • 최상위 노드인 1번을 조회하면 자식인 2,3,4,5,6,7까지 모두 조회된다.

부모 타입으로 조회하기

  • 이번에도 static class로 새로운 config를 해주었다.
  • 같은 부모를 상속하고 있다.(DiscountPolicy)
  • 타입으로 조회했을 때 둘 이상 있으므로 중복 오류가 발생할 것이다.
  • 이를 assertThrows로 예외처리 해주었다.

 

 

중복 시, 빈 이름 지정

  • 위에서 이미 설명을 했기에 설명 생략

 

특정 하위 타입으로 조회

  • Bean에 등록되어 있는 RateDiscountPolicy는 하나밖에 없기 때문에 이렇게 사용 가능
    • 하지만 좋은 방법 아님.
    • 구체에 의존

 

 

 

부모 타입으로 모두 조회(getBeansOfType)

 

 

 

Object 타입으로 조회하기

  • Spring이 내부적으로 사용하는 Bean까지 모두 조회되는 것을 확인할 수 있다.
  • 모든 Java클래스는 Object클래스를 상속받고 있기 때문에 Object타입으로 조회하면 모든 Bean이 꺼내짐.

 

 

반응형

'Spring > Spring Core' 카테고리의 다른 글

다양한 설정 형식 지원  (0) 2021.03.10
BeanFactory와 ApplicationContext  (0) 2021.03.09
Container에 등록된 Bean 조회  (0) 2021.03.08
Spring Container  (0) 2021.03.08
Spring으로 변환 (자~~ 드가자~)  (0) 2021.03.05