@Autowired
private DiscountPolicy discountPolicy
@Autowired는 타입으로 조회하기 때문에 ac.getBean(DiscountPolicy.class)와 유사하게 동작한다.
하지만 DiscountPolicy 의 하위 타입인 FixDiscountPolicy , RateDiscountPolicy 둘다 스프링 빈으로 선언하면 문제가 발생한다.
@Component
public class FixDiscountPolicy implements DiscountPolicy {}
@Component
public class RateDiscountPolicy implements DiscountPolicy {}

해결방법
@Autowired 필드 명 매칭
@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = rateDiscountPolicy;
}
}
고정금액 할인으로 적용하고 싶으면 DiscountPolicy rateDiscountPolicy에서 rateDiscountPolicy을 fixDiscountPolicy로 변경하면 된다.
@Qualifier 사용
1. @Qualifier끼리 매칭
2. 빈 이름 매칭
3. NoSuchBeanDefinitionException 예외 발생
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy{
...
}
@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy{
...
}
@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
...
}
@Qualifier 로 주입할 때 @Qualifier("mainDiscountPolicy") 를 못찾으면 mainDiscountPolicy라는 이름의 스프링 빈을 추가로 찾는다. 하지만 경험상 @Qualifier 는 @Qualifier 를 찾는 용도로만 사용하는게 명확하고 좋다.
@Primary 사용
가장 자주 사용하는 방법
@Primary 는 우선순위를 정하는 방법이다.
@Autowired 시에 여러 빈이 매칭되면 @Primary 가 우선권을 가진다.
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy{
...
}
@Component
public class FixDiscountPolicy implements DiscountPolicy{
...
}
참고
우선순위는 @Qualifier가 @Primary보다 우선권이 높다.