목표

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 를 걸어두자고 팀내에서 룰을 지정할 수 있다. 


다음 강의에서는 애노테이션을 직접 만드는 방법 배운다. 

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

728x90

+ Recent posts