끄적끄적 코딩일지

[Spring 기초] @Qualifier, @Primary 본문

Spring

[Spring 기초] @Qualifier, @Primary

BaekGyuHyeon 2022. 5. 30. 15:06

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가 우선권을 가진다.