조회 대상 빈이 2개 이상일 때 앞서 배웠던 것 처럼 오류가 발생하게 된다.
이를 해결하는 방법을 하나씩 알아보자.
조회 대상 빈이 2개 이상일 때 해결 방법
- @Autowired 필드명 매칭
- @Qualifier → @Qualifier끼리 매칭 → 빈 이름 매칭
- @Primary 사용
@Autowired 필드명 매칭
@Autowired는 먼저 타입 매칭을 시도하고, 이때 여러 빈이 있다면 필드 이름, 파라미터 이름으로 빈 이름을 추가 매칭한다.
기존코드
@Autowired
private DiscountPolicy discountPolicy
필드명을 빈 이름으로 변경
@Autowired
private DiscountPolicy rateDiscountPolicy
필드명이 rateDiscoutPolicy이므로 정상 주입된다.
필드명 매칭은 먼저 타입 매칭을 시도하고 그 결과에 여러 빈이 있을 때 추가적으로 동작하는 기능이다.
타입 매칭 → 타입 매칭이 2개 이상일 때 필드명, 파라미터명으로 빈 이름 매칭
@Qualifier 사용
@Qualifier는 추가 구분자를 붙여주는 방법이며, 주입 시 추가적인 방법을 제공하는 것이지 빈 이름을 변경하지는 않는다.
빈 등록시 @Qualifier("mainDiscountPolicy")
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {}
생정자 자동 주입 예시
@Autowired
public OrderServiceImpl(@Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy, ...) {
this.discountPolicy = discountPolicy;
...
}
수정자 자동 주입 예시
@Autowired
public DiscountPolicy setDiscountPolicy(@Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
@Qualifier로 주입할 때 @Qualifier("mainDiscountPolicy")를 못 찾으면 어떻게 될까? 그러면 "mainDiscountPolicy"라는 이름의 스프링 빈을 추가로 찾는다. 하지만 @Qualifier는 @Qualifier 를 찾는 용도로만 사용하는게 명확하고 좋다.
수동 빈 등록시에도 @Qualifier를 사용할 수 있다.
@Bean
@Qualifier("mainDiscountPolicy")
public DiscountPolicy discountPolicy() {
return new ...
}
@Primary 사용
@Primary는 우선 순위를 정하는 방법으로, @Autowired 시에 여러 빈이 매칭되면 @Primary가 우선권을 가지게 된다.
rateDiscountPolicy가 우선권을 가지도록 하자.
@Primary
@Component
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
public class FixDiscountPolicy implements DiscountPolicy {}
//생성자
@Autowired
public OrderServiceImpl(DiscountPolicy discountPolicy, ...) {
this.discountPolicy = discountPolicy;
...
}
//수정자
@Autowired
public DiscountPolicy setDiscountPolicy(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
코드를 실행해보면 @Primary를 가진 클래스가 주입된다. @Qualifier는 주입 받는 모든 코드에 @Qualifierfmf 붙어야 하는 번거로움이 있다. 반면 @Primary는 등록되는 클래스에 붙여주기만 하면 된다.
만약 @Primary가 여러 개인 경우 → NoSuchBeanDefinitionException 오류가 발생한다.
@Primary vs @Qualifier
@Primary와 @Qualifier를 적절히 사용하는 것이 가장 이상적이라고 볼 수 있다. @Primary는 하나의 구현체 만 사용하고 @Qualifier는 디테일하게 접근하고 사용할 수 있다. 서로 같이 쓰이는 경우 @Qualifier가 우선순위가 더 높다.
Reference
스프링 핵심 원리 - 기본편 - 인프런 | 강의
스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., - 강의 소개 | 인프런...
www.inflearn.com
'Spring > Spring 핵심 원리' 카테고리의 다른 글
[Spring] 조회한 빈이 모두 필요한 경우 (List, Map) (0) | 2022.12.26 |
---|---|
[Spring] @Qualifier 문제점, 직접 애너테이션 만들기 (0) | 2022.12.26 |
[Spring] @Autowired란? (0) | 2022.12.26 |
[Spring] @ComponentScan이란? (0) | 2022.12.26 |
[Spring] 싱글톤(Singleton) 패턴과 @Configuration (0) | 2022.12.26 |