-
(스프링 기본) 22 - 조회된 빈이 2개 이상 문제 (@Qualifier, @Primary)개발/Spring 2024. 10. 28. 14:57
■ 조회된 빈이 2개 이상 발견 되면 생기는 문제 (UnsatisfiedDependencyException)
@Component public class OrderServiceImpl implements OrderService { private final MemberRepository memberRepository; private final DiscountPolicy discountPolicy; @Autowired public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) { this.memberRepository = memberRepository; this.discountPolicy = discountPolicy; }
@Autowired 는 타입으로 조회한다.
즉, ac.getBean(DiscountPolicy.class) 와 유사하게 동작한다.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderServiceImpl' defined in file [C:\study\core\build\classes\java\main\hello\core\order\OrderServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 1: No qualifying bean of type 'hello.core.discount.DiscountPolicy' available: expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy
그런데 선택된 빈이 2개 이상이면 오류가 발생한다.
■ 조회된 빈 2개 이상일 때 해결 방법
1. @Autowired 필드명 매칭
2. @Qualifier -> @Qualifier 매칭 -> 빈 이름 매칭
3. @Primary 사용
1. @Autowired 필드명 매칭
@Autowired public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy) { this.memberRepository = memberRepository; this.discountPolicy = rateDiscountPolicy; }
타입 매칭 시도하고, 여러 빈이 있다면 필드 이름, 파라미터 이름으로 빈 이름을 추가 매칭한다.
다음과 같이 파라미터를 rateDiscountPolicy 로 바꿔주니 오류가 해결되었다.
@Autowired private DiscountPolicy rateDiscountPolicy;
필드명 파라미터를 변경해줘도 된다.
* @Autowired 필드명 매칭 정리
1) 타입 매칭
2) 타입 매칭 결과 2개 이상일 경우,,= 필드명 또는 파라미터 명으로 빈 이름 매칭
2. @Qualifier 사용
@Qualifier 는 추가 구분자를 붙여주는 방법이다.
즉, 주입 시 추가적인 방법 제공이지 빈 이름 변경이 아니다.
@Component @Qualifier("mainDiscountPolicy") public class RateDiscountPolicy implements DiscountPolicy{
주로 쓰는 빈을 @Qualifier 로 등록한다.
@Autowired public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) { this.memberRepository = memberRepository; this.discountPolicy = discountPolicy; }
그리고 의존성 주입 시 @Qualifier(mainDiscountPolicy) 를 넣어주면
해당 @Qualifier 로 등록된 의존성을 주입시켜 준다.
* @Qualifier 매칭 정리
1) @Qualifier 끼리 매칭
2) 빈 이름 매칭
3) NoSuchBeanDefinitionException 예외 발생
3. @Primary 사용
@Component @Primary public class RateDiscountPolicy implements DiscountPolicy{
@Primary 는 우선순위를 정하는 것이다.
@Primary 가 우선권을 가진다.
■ 활용
@Primary : 메인 데이터베이스 커넥션 획득하는 스프링 빈
@Qualifier : 서브 데이터베이스 커넥션 빈을 획득할 때
스프링은 자동보다 수동, 넓은 범위보다 선택권이 좁은 범위가 우선 순위가 높다.
즉 @Qualifier 가 우선순위가 더 높다.
출처 : 김영한 스프링 핵심 원리 - 기본편
'개발 > Spring' 카테고리의 다른 글
(스프링 기본) 24 - 조회된 빈이 모두 필요할 때 (List, Map) (0) 2024.10.28 (스프링 기본) 23 - 어노테이션 만들기 (0) 2024.10.28 (스프링 기본) 21 - 롬복 사용하기 (@Getter, @Setter + 생성자 주입 깔끔하게 넣기) (0) 2024.10.28 (스프링 기본) 20 - 생성자 주입 선택해야 하는 이유 (1) 2024.10.28 (스프링 기본) 19 - 옵션 처리 (0) 2024.10.28