[Spring 기초] @Qualifier, @Primary
Spring에서 DI를 사용하다보면 대상의 Bean이 2개 이상인 경우가 있다.
예를들어 할인정책을 DiscountPolicy라는 추상화 객체로 만들고 고정할인인 FixDiscountPolicy와 구매 금액에 따라 일정 비율만큼 할인해주는 RateDiscountPolicy를 구현체로 만들고 Bean으로 등록했다고 해보자.
// 추상화
@Component
public interface DiscountPolicy{
public int discount(int cost);
}
//구체화
@Component
public class FixDiscountPolicy implement DiscountPolicy{
@Override
public int discount(int cost){ return cost - 1000;}
}
@Component
public class RateDiscountPolicy implement DiscountPolicy{
@Override
public int discount(int cost){ return cost - (cost * 1/10);}
}
두 구체화 객체 모두 Bean으로 등록되어있고 사용할때는 FixDiscountPolicy와 RateDiscountPolicy를 구분해서 사용해야한다. 하지만 직접
@Autowired
private FixDiscountPolicy policy
등으로 사용하는건 의존관계가 강해지고 변경사항 발생시 수정해야 하는 코드량이 늘어난다.(DIP 위반) 때문에
@Autowired private
private DiscountPolicy policy
등으로 하되 주입받는 bean을 구분할 필요가 있다. 그 방법에는 크게 3가지가 있다.
1. 필드명 매칭
@Autowired
private DiscountPolicy fixDiscountPolicy // FixDiscountPolicy 매칭
@Autowired
private DiscountPolicy rateDiscountPolicy // RateDiscountPolicy 매칭
똑같은 타입의 Bean이 2개 이상 조회가 될시 Spring에서는 필드 명 또는 파라미터명을 구분하여 매칭을 한다.
2. Qualifier 사용
빈 등록시 @Qualifer("구분자 이름")을 사용하여 추가 구분자를 붙이는 방법도 있다.
@Component
@Qualifier("fixDiscount")
public class FixDiscountPolicy implement DiscountPolicy{
@Override
public int discount(int cost){ return cost - 1000;}
}
@Component
@Qualifier("rateDiscount")
public class RateDiscountPolicy implement DiscountPolicy{
@Override
public int discount(int cost){ return cost - (cost * 1/10);}
}
// 사용
@Autowierd
@Qualifier("rateDiscount")
private DiscountPolicy policy; // RateDiscountPolicy 메핑
@Autowired
public Constructor(@Qualifier("fixDiscount") DiscountPolicy policy){
this.policy = policy // fixDiscountPolicy 메핑
}
단 Qualifier를 사용시 중복되는 타입의 모든 Bean에게 Qualifier를 붙여야 한다는 단점이 있다.
3. @Primary 사용
@Primary를 주어 같은 타입의 Bean이 2개이상 조회가 될시 @Primary가 있는 bean이 우선권을 가지도록 한다. 즉 기본값을 지정해 주는것
@Component
@Primary
public class FixDiscountPolicy implement DiscountPolicy{
@Override
public int discount(int cost){ return cost - 1000;}
}
@Component
public class RateDiscountPolicy implement DiscountPolicy{
@Override
public int discount(int cost){ return cost - (cost * 1/10);}
}
@Autowierd
private DiscountPolicy policy; // FixDiscountPolicy 메핑
※ 만약 Primary와 Qualifier를 동시에 사용할 경우 Qualifier가 우선권을 가진다.