본문 바로가기
Spring

조회 빈이 2개 이상일 때 해결방법!

by 쁘니쁘나 2022. 6. 4.

 

조회 빈이 2개 이상일 경우 해결방법!

 

@Autowired 필드명 매칭

빈 조회시 타입으로 매칭이 되지만 동일 타입이 2개이상인 빈에 대해서는 타입 다음 필드(파라미터)명으로 빈을 조회 하게 된다. 따라서 동일 타입에 대해 필드(파라미터)명을 다르게 해주면 빈 충돌이 나지 않게된다!

@Autowired 
  public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy) { // ✅ 이렇게 파라미터명을 rate~로 다르게 해주면 충돌나지 않음!
    this.memberRepository = memberRepository;
    this.discountPolicy = rateDiscountPolicy;
  }

 

@Qualifier → @Qualifier 끼리 매칭 → 빈 이름 매칭

빈이름을 변경하는 것이 아니라 @Quilifier(”빈이름지정”) 이 어노테이션을 사용하여 찾는것이다. 아래 예시로 이해해보자.

이렇게 파라미터에 @Qualifier(”mainDiscountPolicy”) 를 붙이게 되면 그 밑의 RateDiscountPolicy 예제와 같이 @Qualifier 어노테이션이 붙은 것중 괄호안에 mainDiscountPolicy 가 명시되어 있는 빈이 매칭된다.

@Component
public class OrderServiceImpl implements OrderService {

  private final MemberRepository memberRepository;
  private final DiscountPolicy discountPolicy;

  @Autowired // 얘를 생성할때 ApplicationContext에서 자동으로 memberRepository와 discountPolicy를 의존관계 주입으로 넣어준다.
  public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
  }
}
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {

  private int discountPercent = 10;

  @Override
  public int discount(Member member, int price) {
    if(member.getGrade() == Grade.VIP) {
      return price * discountPercent / 100;
    } else {
      return 0;
    }
  }
}

 

그런데 만약 @Qualifier 어노테이션이 붙은 것중 mainDiscountPolicy 라는 것이 없다면⁉

그럴때는 스프링컨테이너에 등록된 mainDiscountPolicy 라는 이름의 스프링빈을 추가로 찾는다. 하지만 @Qualifier 는 @Qualifier로 명시되어있는 것만 찾도록 사용하는것이 명확하고 좋다!

 

@Primary 사용

우선순위를 나타내는 어노테이션이다. @Autowired 시에 여러개의 빈이 매칭되면 @Primary 가 붙은 빈이 우선권을 가진다! 아래 예시는 두개의 클래스를 같이 보여주는 예시이다. 두개의 클래스에서 @Primary 가 붙은 RateDiscountPolicy 클래스가 빈으로 등록이 된다

@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {...}

@Component
public class FixDiscountPolicy implements DiscountPolicy {...}

 

@Qualifier 와 @Primary중 어떤것을 사용하는게 좋을까??

@Primary 는 기본값처럼 동작하지만, @Qualifier 는 우리가 하나하나 명시해줘야하므로 더 상세하다. 이런경우 스프링은 자동보다는 수동이, 넓은 범위의 선택권 보다는 좁은 범위의 선택권이 우선 순위가 더 높다! 따라서 @Qualifier 가 우선권이 더 높으니 해당 어노테이션을 사용하자!!

 

 

 

 

 

참고


인프런 - 김영한의 스프링 기본편

댓글