@Autowired는 타입으로 조회한다
타입으로 조회하면 같은 타입의 빈이 2개 이상일 때 문제가 발생한다.
예를 들어 DiscountPolicy의 하위 타입인 FixDiscountPolicy, RateDiscountPolicy둘다 스프링 빈으로 등록시키고
@Autowired
private DiscountPolicy discountPolicy
위와 같이 DiscountPolicy타입으로 의존관계를 주입하면 NoUniqueBeanDefinitionException오류가 발생한다.
해결방법으로 하위타입을 이용해서 의존관계를 주입하면 DIP를 위배하고 유연성이 떨어진다.
해결방법에는 크게 3가지가 있다.
- @Autowired 필드 명 매칭
- @Qualifier사용
- @Primary사용
@Autowired 필드 명 매칭
@Autowired는 타입 매칭을 시도하고 여러 빈이 있으면 필드 이름, 파라미터 이름으로 빈 이름을 추가 매칭한다.
기본 코드를 필드 명을 빈 이름으로 변경해 보자
@Autowired
private DiscountPolicy rateDiscountPolicy
필드 명을 rateDiscountPolicy로 변경해 주면 rateDiscountPolicy빈이 등록된다.
@Qualifier사용
@Qualifier은 추가 구분자를 붙여주는 방법이다.
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy{}
@Component
@Qualifier("subDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {}
RateDiscountPolicy에는 main을 FixDiscountPolicy sub라고 붙여준다.
그리고 생성자 자동 주입 시에 주입을 할 Qualifier의 이름을 적어주면 된다.
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy")DiscountPolicy discountPolicy)
{
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
이렇게 생성자 주입을 하면 mainDiscountPolicy인 RateDiscountPolicy가 주입된다.
이때 @Qualifier("mainDiscountPolicy")를 찾지 못하면 스프링 빈이름이 mainDiscountPolicy인 빈을 찾는다.
이도 없으면 에러를 발생시킨다
@Primary사용
@primary는 우선순위를 정하는 방법이다.
@primary애노테이션을 붙여주면 우선순위를 가지게 된다.
rateDiscountPolicy가 우선권을 가지게 해 보자
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy{}
이렇게 애노테이션을 달아주면 rateDiscountPolicy가 주입된다.
@Primary와 @Qualifier의 우선순위는 좀 더 상세하게 동작하는 @Qualifier이 가지게 된다.
출처 : 인프런 스프링 핵심 원리 - 기본 편 김영한
'스프링' 카테고리의 다른 글
빈 생명주기 콜백 (0) | 2023.07.24 |
---|---|
동일 타입 2개 이상의 빈이 모두 필요할 때 (0) | 2023.07.22 |
생성자 주입의 장점, 룸복사용 (0) | 2023.07.21 |
다양한 의존관계 주입 방법 (0) | 2023.07.19 |
스프링 빈 필터 (0) | 2023.07.18 |