1. 조회 빈이 2개 이상인 경우
(1) 문제 발생
- @Autowired는 타입(Type)으로 조회한다.
- 타입으로 조회하기 때문에 ac.getBean(DiscountPolicy.class)와 유사하게 동작
- 스프링 빈 조회에서 학습했듯이 타입으로 조회하면 선택된 빈이 2개 이상일 때 문제가 발생
DiscountPolicy의 하위 타입인 FixDiscountPolicy, RateDiscountPolicy 둘 다 스프링 빈으로 선언
@Component
public class FixDiscountPolicy implements DiscountPolicy {}
@Component
public class RateDiscountPolicy implements DiscountPolicy {}
@Autowired
private DiscountPolicy discountPolicy
- 이후 의존관계 자동 주입을 실행하면 NoUniqueBeanDefinitionException 발생한다.
(2) 해결 방법
- @Autowired 필드 명 매칭
- @Qualifier -> @Qualifier끼리 매칭 -> 빈 이름 매칭
- @Primary 사용
(2-1) @Autowired 필드 명 매칭
@Autowired는 타입 매칭을 시도하고, 이때 여러 빈이 있으면 필드 이름, 파라미터 이름으로 빈 이름을 추가 매칭 한다.
@Autowired
private DiscountPolicy rateDiscountPolicy
- 필드 명이 rateDiscountPolicy이므로 정상 주입된다.
- 필드 명 매칭은 먼저 타입 매칭을 시도하고 그 결과에 여러 빈이 있을 때 추가로 동작하는 기능
(2-2) @Qualifier 사용
@Qualifier는 추가 구분자를 붙여주는 방법. 주입 시 추가적인 방법을 제공하는 것이다.
- @Qualifier 사용 시 매칭 순서
- @Qualifier끼리 매칭
- 빈 이름 매칭
- NoSuchBeanDefinitionException
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}
- 빈 등록 시 @Qulifier를 붙여 준다.
@Autowired
public OrderServiceImpl(MemberRepository memberRepository,
@Qualifier("mainDiscountPolicy") DiscountPolicy
discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
- 생성자 주입 시 @Qulifier를 붙여준다.
- @Qualifier로 주입할 때 @Qualifier("mainDiscountPolicy")를 못 찾으면 mainDiscountPolicy라는 이름의 스프링 빈을 추가로 찾는다. (하지만 이렇게 사용되는 것을 지양해야 한다.)
(2-3) @Primary 사용
@Primary는 우선순위를 정하는 방법이다. @Autowired 시에 여러 빈이 매칭 되면 @Primary가 우선권을 가진다.
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
public class FixDiscountPolicy implements DiscountPolicy {}
- rateDiscountPolicy가 우선권을 가진다.
//생성자
@Autowired
public OrderServiceImpl(MemberRepository memberRepository,
DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
- 코드가 가장 깔끔해진다.
2. 정리
- 코드에서 자주 사용하는 스프링 빈 : @Primary 사용
- ex) 메인 데이터베이스의 커넥션을 획득하는 스프링 빈
- 특별한 기능으로 가끔 사용하는 스프링 빈 : @Qualifier 사용
- ex) 서브 데이터베이스 커넥션 빈을 획득하는 스프링 빈
- 우선순위
- 스프링은 자동보다는 수동, 넓은 범위의 선택권보다는 좁은 범위의 선택권이 우선순위가 높다.
- @Qualifier의 우선권이 높다.
본 글은 김영한 님의 "스프링 핵심 원리"(인프런) 유료 강의를 들으며 요약, 정리하고 일부 정보를 추가 작성한 것입니다.
반응형
'Spring(JAVA Framework) > Spring Core' 카테고리의 다른 글
조회한 모든 빈이 가져오기 (List, Map) (0) | 2021.08.19 |
---|---|
Lombok 라이브러리 (0) | 2021.08.19 |
의존관계 자동 주입 방법 (0) | 2021.08.19 |
컴포넌트 스캔 (Component Scan) (0) | 2021.08.18 |
Singleton (싱글톤) (0) | 2021.08.18 |
댓글