동일한 타입의 여러 클래스가 스프링 빈으로 등록되어 있을 때 다음과 같은 방법으로 원하는 빈을 설정할 수 있다.

@Autowired 필드명 매칭

@Autowired
private DiscountPolicy rateDiscountPolicy;

@Qualifier 사용

RateDiscountPolicy.java

@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy {

		...
}

OrderServiceImpl.java

@Autowired
public OrderServiceImpl(MemberRepository memberRepository, 
												@Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
		this.memberRepository = memberRepository;
		this.discountPolicy = discountPolicy;
}

@Primary 사용

@Component
@Primary // 우선권을 가짐
public class RateDiscountPolicy implements DiscountPolicy {}

@Component
public class FixDiscountPolicy implements DiscountPolicy {}

@Qualifier and @Primary

주된 빈에는 @Primary 를 붙여주고 서브 타입의 빈에는 @Qualifier 를 붙여주어 두 방식을 한번에 사용할 수도 있다.

우선순위

@Primary 는 기본값처럼 동작하는 것이고, @Qualifier 는 매우 상세하게 동작한다. 스프링은 자동보다는 수동이, 넓은 범위의 선택권보다는 좁은 범위의 선택권이 우선 순위가 높다. 따라서 여기서도 @Qualifier 가 우선권이 높다.