동일한 타입의 여러 클래스가 스프링 빈으로 등록되어 있을 때 다음과 같은 방법으로 원하는 빈을 설정할 수 있다.
@Autowired
private DiscountPolicy rateDiscountPolicy;
스프링 빈들에게 별칭을 붙이고 해당 별칭을 이용해서 찾을 수 있다.
처음에는 @Qualifier
를 이용해서 찾고 없으면 해당 이름(ex. mainDiscountPolicy) 을 가지는 빈을 찾으나 되도록 @Qualifier
는 @Qualifier
를 붙인 빈에서만 찾도록 설정하는 것이 좋다.
단점은 빈을 호출하는 모든 곳에서 @Qualifier
를 붙여주어야 한다.
또한 롬복을 사용할 경우 롬복은 이 어노테이션을 읽지 않는다.
Lombok does not copy the annotation 'org.springframework.beans.factory.annotation.Qualifier' into the constructor
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;
}
@Autowired
시에 여러 빈이 매칭되면 @Primary
가 우선권을 가진다.@Component
@Primary // 우선권을 가짐
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
public class FixDiscountPolicy implements DiscountPolicy {}
주된 빈에는 @Primary 를 붙여주고 서브 타입의 빈에는 @Qualifier 를 붙여주어 두 방식을 한번에 사용할 수도 있다.
@Primary 는 기본값처럼 동작하는 것이고, @Qualifier 는 매우 상세하게 동작한다. 스프링은 자동보다는 수동이, 넓은 범위의 선택권보다는 좁은 범위의 선택권이 우선 순위가 높다. 따라서 여기서도 @Qualifier
가 우선권이 높다.