목표
1. 조회할 빈이 2개 이상일 때의 문제를 어떻게 처리해야 할지 배운다.
2. @Autowired 필드 명을 매칭, @Qualifier, @Primary 사용법을 배운다.
'의존관계 자동 주입' 목차
1. 다양한 의존관계 주입 방법
2. 옵션 처리
3. 생성자 주입을 선택해라!
4. 롬복과 최신 트랜드
5. 조회 빈이 2개 이상 - 문제 (이번 포스팅)
6. @Autowired 필드 명, @Qualifier, @Primary
7. 애노테이션 직접 만들기
8. 조회한 빈이 모두 필요할 때, List, Map
9. 자동, 수동의 올바른 실무 운영 기준
5. 조회할 빈이 2개 이상일 때의 문제 해결하기
@Autowired 는 타입으로 빈을 조회한다.
1) 만약 타입이 같은 빈이 2개가 조회되면 문제가 생길까?
인터페이스 DiscountPolicy의 구현체 2개가 있다. RateDiscountPolicy와 FixDiscountPolicy 는 타입이 같다.
RateDiscountPolicy 만 컴포넌트 스캔으로 스프링 빈 등록했었는데. FixDiscountPolicy도 스프링 빈 등록하려고 한다.
스프링 빈 등록을 위해 컴포넌트 스캔을 하자.
2) orderServiceImple 에서 의존성 예외 발생했는데, DiscountPolicy 싱글 빈이 매칭되기를 기대했는데, 2개가 발견됬기 때문이다.
beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'orderServiceImpl' Unsatisfied dependency
nested exception is NoUniqueBeanDefinitionException:
No qualifying bean of type 'DiscountPolicy' available:
expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy
@Autowired 로 의존관계를 주입하려고 DiscountPolicy 타입의 스프링 빈을 뒤져봤더니
1개 매칭을 기대했는데, 2개의 스프링 빈이 RateDiscountPolicy와 FixDiscountPolicy 발견되서 에러가 났다.
3) 하위 타입인 fixDiscountPolicy 나 rateDiscountPolicy 를 적어야 할까? 아니다. 하위타입에 의존하면 DIP를 위반한다.
다음 시간에 해결책을 배워보자.
6. @Autowired 필드 명, @Qualifier, @Primary
타입이 같은 빈이 여러개 조회되면, 3가지 방법으로 해결할 수 있다.
1) @Autowired 필드 명을 매칭한다
@Autowired 의 스프링 빈 조회 순서-> 1. 타입 매칭, 2. 필드 명 또는 파라미터 명을 매칭
@Autowired 는 가장 먼저 스프링 빈의 타입을 매칭해보고. 빈이 2개 이상 조회되면 필드 명을 확인해서 매칭되는 하나를 조회한다.
이전 코드
@Autowired 필드 명을 매칭시키도록 변경한 코드
2) @Qualifier 추가 구분자를 붙여주기
추가적인 방법을 제공하는 것이지 빈 이름을 변경하는건 아니다.
예를 들어, RateDiscountPolicy 에 @Qualifier("mainDiscountPolicy") 를 지정하고,
FixDiscountPolicy 에는 @Qualifier("fixDiscountPolicy") 를 지정한다.
생성자 주입을 할 때 @Qualifier를 써주면 된다.
만약 해당 @Qualifier를 못찾으면 스프링은 그 이름으로 등록된 빈을 찾아본다.
@Qualifier의 스프링 빈 조회 순서-> 1. @Qualifier 끼리 매칭, 2. 빈 이름 매칭
@Qualifier 는 @Qualifier 를 찾는 용도로만 사용하는게 명확하고 좋다. 헷갈리게 하는 요소를 만들지 말자.
3) @Primary 우선순위를 지정하기 [ 편하고 자주 사용한다 ]
rate 할인정책을 항상 먼저 적용하고 싶다면, RateDiscountPolicy에 @Primary 를 붙인다.
생성자에는 DiscountPolicy 타입 그대로 둔다.
[ 참고 ] @Primary 는 언제 사용할까?
예를 들어, 메인 DB connection 을 주로 사용하고, 백업용 DB connection 이 있는 상황에서,
메인 DB connection 에 @Primary 를 걸어두자고 팀내에서 룰을 지정할 수 있다.
다음 강의에서는 애노테이션을 직접 만드는 방법을 배운다.
공부 내용 출처 : 스프링 핵심 원리 기본편
'프로그래밍 > Spring Basic' 카테고리의 다른 글
18. 조회한 빈이 모두 필요할 때 List, Map에 담기 (0) | 2021.12.27 |
---|---|
17. 애노테이션 직접 만들기 (0) | 2021.12.27 |
15. 생성자 주입을 선택해야하는 이유와 롬복 (0) | 2021.12.27 |
14. 다양한 의존관계 주입 방법 (0) | 2021.12.26 |
13. 컴포넌트 스캔의 필터와 빈 이름 중복 (0) | 2021.12.25 |