Dev/Spring

[스프링 핵심 원리] @Qualifier, @Primary와 Bean 우선순위

oxdjww 2023. 9. 26. 18:06
728x90
반응형

Intro

본 카테고리는 Inflearn 김영한 강사님의 스프링 핵심 원리 강의를 수강하며 이해하고 학습한 내용을 정리한 내용으로 구성되어 있다.

본 포스팅에서는 빈 조회 시 중복된 빈들에 대해 우선순위를 적용해 보다 쉽게 빈을 찾을 수 있는 방법에 대해 다룬다.

@Autowired


@Autowired 어노테이션은 기본적으로 Type으로 빈을 조회하여 DI한다.
이는 ac.getBean(DiscountPolicy.class) 와 유사하게 동작하는 것으로 볼 수 있다.

즉, interfaceDiscountPolocy.class로 조회 시, 해당 interface를 구현한 FixDiscountpolicy.classRateDiscountPolicy 두 개가 스프링 빈으로 모두 등록되어 있으면 문제가 발생한다는 것이다.
한 마디로 정리하자면 타입으로 조회하였기 때문에 선택할 수 있는 빈이 2개 이상 이면 예외가 발생한다.

이를 어떻게 해결할 수 있을까?

How to Solve


  1. @Autowired 필드 명 매칭
  2. @Qualifer 식별자 사용
  3. @Primary로 우선순위 부여

1. @Autowired 필드 명 매칭


  • 기존 코드
@Autowired
private DiscountPolicy discountPolicy
  • 필드 명을 빈 이름으로 변경
@Autowired
private DiscountPolicy rateDiscountPolicy

DIP를 위반하지 않기 위해 자료형을 구체화된 클래스로 변경하는 것이 아니라, 필드명 을 변경해주는 방법이다.

스프링은 타입 매칭을 시도하고, 중복된 빈이 조회되었기 때문에 추가로 필드명을 바탕으로 빈을 선택하게 된다.

2. @Qualifer 식별자 사용


추가 식별자를 부여하여 빈을 식별할 수 있도록 해주는 방법도 있다.

  • 빈 등록시 @Qualifer를 붙인다.
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {} ```
  • 주입 시에 @Qualifer를 통해 빈 등록시 부여한 이름을 식별할 수 있도록 한다.
@Autowired
public OrderServiceImpl(MemberRepository memberRepository,
                        @Qualifier("mainDiscountPolicy") DiscountPolicy
discountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
}

@Qualifer로 매칭되는 빈을 찾지 못 하면 해당 식별자와 이름이 같은 빈을 찾는다.
(위의 예제에서는 mainDiscountPolicy로 등록된 빈)

그렇게 매칭해도 찾지 못 하는 경우에는 NoSuchBeanDefinitionException 예외가 발생한다.

3. @Primary로 우선순위 부여


여러 빈이 조회되었을시에 우선순위를 정한 빈을 선택하는 방법이다.

할인정책(DiscoutPolicy) 중 정률할인정책인 RateDiscountPolicy가 기본(primary)값을 가진다고 하자.
그럼 다음과 같이 한 줄을 추가하면 된다.

@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {}

@Primary, @Qualifier 활용


활용하는 예를 들자면,
어플리케이션에서 여러 database를 이용하는 상황을 가정해보자.

Main database는 @Primary로 지정하고, sub database는 @Qualifier("subDB")로 하면 될 것이다.

@Primary vs. @Qualifier


@Primary는 기본값처럼 동작하고, @Qualifier는 상세하게 동작한다.
두 개의 옵션이 공존할 때, 어느 것이 우선순위를 가질까?

스프링은 항상 수동으로 설정해준 것이 자동보다 우선권을 가진다.
그러므로, @Qualifier가 우선권이 높다고 할 수 있다.

  • @Primary로 등록된 RateDiscountPolicy가 선택된 모습


감사합니다.

728x90
반응형