목표

1. 스프링 빈 조회 방법을 배운다.
2. BeanFactory와 ApplicationContext 의 차이를 배운다.

'스프링 컨테이너와 스프링 빈' 목차

1. 스프링 컨테이너 생성  

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

3. 스프링 빈 조회 - 기본

4. 스프링 빈 조회 - 동일한  타입이 둘 이상 (이번 포스팅)

5. [ 중요 ] 스프링 빈 조회 - 상속 관계

6. BeanFactory와 ApplicationContext 

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

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


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

1) 타입으로 조회 시, 같은 타입이 2개 이상 있으면 중복 오류가 발생한다. 

임시로 MemberRepository 타입 빈이 2개 있는 SameBeanConfig.class 설정 파일을 만들었다. 

여기서 MemberRepository.class 타입 빈을 가져오면? 

아래와 같은 NoUniqueBeanDefinitionException 이 발생한다. 설명이 굉장히 친절하다.

싱글 매칭 빈을 기대했는데, 2개 였다는 내용. 

org.springframework.beans.factory.NoUniqueBeanDefinitionException
: No qualifying bean of type 'hello.corebasic.member.MemberRepository' available
: expected single matching bean but found 2: memberRepository1,memberRepository2

 

이렇게 특정 에러가 발생하는지 확인하려면 assertThrow와 Exception 클래스명을 써서 확인한다.

2) 타입으로 조회 시, 같은 타입이 2개 이상 있으면 빈 이름을 지정하면 된다!

빈 이름은 중복 불가다. 빈 이름을 안겹치게 지어서 조회하면 된다.

3) 특정 타입을 모두 조회하기

getBeansOfType() 메서드로 Map<이름, 타입> 특정 타입의 모든 빈을 모두 조회할 수 있다. 

나중에 @Autowired같이 자동으로 주입되는 기능을 배울 때 이런식으로 적용이 된다. 

ac.getBeansOfType(MemberRepository.class);


[ 중요 ] 5. 스프링 빈 조회 - 상속 관계 

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

스프링 빈 대 원칙 하나는 "스프링 빈 하나 조회하면? 그 빈의 자식을 싹다 조회한다. " 

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

테스트 코드로 확인하자. TestConfig 설정파일을 하나 만들자. DiscountPolicy 이름으로 생성될 빈이 2개다!  반환되는 생성자만 다르다. 

2) 부모 타입을 조회하면, 자식까지 다 딸려서 조회되니까 자식이 둘 이상인 경우 오류가 발생한다. 

이럴 땐 이름을 지어서 구분하면 된다. 

3) 부모 타입을 조회 시, 자식이 둘 이상 있으면, 빈 이름을 지정하면 된다. 

rateDiscountPolicy 특정 빈 이름으로 조회하자. 

4) 특정 하위 타입으로 조회할 수 있다. 

구체적인 타입으로 딱 지정하면 조회할 수 있지만 안 좋은 방법이다. 

5) 부모 타입으로 모두 조회해보자. 

할인 정책 인터페이스를 구현한 구현체 클래스 2개가 조회 된다. 

rateDiscountPolicy, fixDiscountPolicy 자식 타입 스프링 빈 2개가 출력됨을 확인할 수 있다. 

[ 참고 ] 실무에서 테스트 코드를 작성할 때는 이렇게 출력물을 만들면 안된다

지금은 공부용이라서 system.out.print를 하지만, 실무에서 테스트 코드를 작성할 때는 이렇게 출력물을 만들면 안된다. 

테스트 통과/실패 여부만 판단하도록 작성하는게 좋다. 

 

6) 최고 부모 타입인 Object 로 조회해보자. 

모든 자바 객체의 부모는 Object 라서. 모든 스프링 빈이 조회된다. 

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

실무에서는 ApplicationContext를 통해 getBean() 빈을 조회할 일이 거의 없다. 스프링 컨테이너가 자동으로 의존관계를 주입해주기 때문이다.

굳이 이렇게 배운 이유는, 빈 조회는 스프링의 기본 기능이기도 하고 아주 가끔 순수한 자바 애플리케이션에서 스프링 컨테이너를 생성해서 사용할 일이 있기 때문이다. 
그리고 부모 타입으로 조회 시, 자식 타입 빈까지 조회됨을 알고 있어야 자동 의존관계 주입을 배울 때 잘 사용할 수 있다.


6. BeanFactory 와 ApplicationContext

BeanFactory 와 ApplicationContext에 대해서 알아보자. 아래 계층 구조를 보자.

  • 최상위에 있는 인터페이스 BeanFactory 가 있다.
  • 최상위에 있는 인터페이스 BeanFactory를 상속받은 인터페이스 ApplicationContext 가 있다. 
  • ApplicationContext 는 BeanFactory에 부가 기능을 더한 것이다. 

BeanFactory

  • BeanFactory 는 스프링 컨테이너의 최상위 인터페이스다. 
  • 스프링 빈을 관리하고 조회하는 역할을 담당한다. 지금까지 빈 조회에 사용한 getBean() 을 BeanFactory이 제공한 것이다. 

ApplicationContext 

  • BeanFactory의 모든 기능을 상속 받아서 제공한다. 

BeanFactory와 ApplicationContext의 차이는 뭘까? 

  • 애플리케이션을 개발할 때는 빈을 관리하고 조회하는 기능은 물론이고 수 많은 부가기능이 필요하다. 
  • ApplicationContext는 아래와 같이 여러 인터페이스를 상속받아서 국제화, 이벤트, 리소스 조회 등의 기능을 제공한다. 
  • 우리는 BeanFactory를 직접 사용할 일은 거의 없고, 빈 관리와 부가기능이 포함된 ApplicationContext를 사용한다. 

메시지 소스를 활용한 국제화 기능 

 : 예를 들어 한국에서 접속하면 한국어로, 영어권에서 접속하면 영어로 출력해준다 

환경 변수 

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

애플리케이션 이벤트

 : 이벤트를 발행하고 구독하는 모델을 편리하게 지원 

편리한 리소스 조회 

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

 

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


다음 강의에서는 '스프링 컨테이너가 지원하는 자바코드, XML 형식의 설정 정보'를 배운다. 

공부 내용 출처 :  스프링 핵심 원리 기본편 

728x90

+ Recent posts