[Spring] 조회 빈이 2개 이상일 때

Narcoker·2023년 8월 14일

Spring

목록 보기
14/19

조회 빈이 2개 이상

상황

현재 존재하는 할인 정책은 두개 이다.

  • FixDiscountPolicy: 1000원 할인 정책
  • RateDiscountPolicy: 10% 할인 정책
@Component
public class FixedDiscountPolicy implements DiscountPolicy {}
@Component
public class RateDiscountPolicy implements DiscountPolicy {}

@Qualifier 사용

@Qualifier 는 추가 구분자를 붙여주는 방법이다.
주입 시 추가적인 방법을 제공하는 것이지 빈 이름을 변경하는 것은 아니다.

빈 등록 시 @Qualifier를 붙인다.

@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {}

주입 시에 @Qualifier를 붙여주고 등록한 이름을 적어준다.

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

@Qualifier("name") -> Annotation 만들기

@Qualifier("mainDiscountPolicy") 이렇게 문자를 적으면 컴파일시 타입 체크가 안된다.
다음과 같은 애노테이션을 만들어서 문제를 해결할 수 있다.

// MainDiscountPolicy 애노테이션 생성
package hello.core.annotataion;
 
import org.springframework.beans.factory.annotation.Qualifier;
import java.lang.annotation.*;

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,
ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Qualifier("mainDiscountPolicy")
public @interface MainDiscountPolicy {}
//생성자 자동 주입
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, @MainDiscountPolicy DiscountPolicy discountPolicy) {
     this.memberRepository = memberRepository;
     this.discountPolicy = discountPolicy;
}

//수정자 자동 주입
@Autowired
public DiscountPolicy setDiscountPolicy(@MainDiscountPolicy DiscountPolicy discountPolicy) {
     this.discountPolicy = discountPolicy;
 }

@Primary 사용

@Primary 는 우선순위를 정하는 방법이다.
@Autowired 시에 여러 빈이 매칭되면 @Primary 가 우선권을 가진다.

RateDiscountPolicy` 가 우선권을 가지도록 하자.

@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {}

@Component
public class FixDiscountPolicy implements DiscountPolicy {}
// 생성자
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
     this.memberRepository = memberRepository;
     this.discountPolicy = discountPolicy;
 }
 
//수정자
@Autowired
public DiscountPolicy setDiscountPolicy(DiscountPolicy discountPolicy) {
     this.discountPolicy = discountPolicy;
 }

@Qualifier VS @Primary

여기까지 보면 @Primary@Qualifier 중에 어떤 것을 사용하면 좋을지 고민이 될 것이다.
@Qualifier 의 단점은 주입 받을 때 다음과 같이 모든 코드에 @Qualifier 를 붙여주어야 한다는 점이다.

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

반면에 @Primary 를 사용하면 이렇게 @Qualifier 를 붙일 필요가 없다.

@Primary 는 기본값 처럼 동작하는 것이고, @Qualifier 는 매우 상세하게 동작한다.

스프링은 자동보다는 수동 이, 넒은 범위의 선택권 보다는 좁은 범위의 선택권이 우선 순위가 높다.
따라서 여기서도 @Qualifier 가 우선권이 높다.

profile
열정, 끈기, 집념의 Frontend Developer

0개의 댓글