Spring

[Spring] 조회된 Bean이 두 개 이상일 때 - @Autowired 필드명, @Qualifier, @Primary

날아 2023. 1. 30. 16:59

0. 조회 대상 빈이 2개 이상일 때 해결 방법

  • @Autowired 필드 명 매칭
  • @Qualifier -> @Qualifier끼리 매칭 -> 빈 이름 매칭
  • @Primary 사용

1. @Autowired 필드 명 매칭

@Autowired가 등록된 빈을 찾을 때는 다음과 같은 매칭 규칙으로 빈을 조회한다.

  1. 주입받고자 하는 타입으로 매칭을 시도한다.
  2. 타입이 여러 개면 필드 또는 파라미터 이름으로 매칭을 시도한다.
  @Autowired
  private DiscountPolicy discountPolicy;
 @Component
  public class FixDiscountPolicy implements DiscountPolicy {}
  
  //그리고 
  
  @Component
  public class RateDiscountPolicy implements DiscountPolicy {}
  
  //이럴 경우 스프링 빈이 2개 조회되서 NoUniqueBeanDefinitionException 오류가 발생한다

해결법 - 필드 명을 빈 이름으로 변경 

  @Autowired
  private DiscountPolicy rateDiscountPolicy;
  
  //이 경우 정상주입 된다.

 

※ 추가로 Spring은 @Resource라는 애노테이션도 제공한다. @Resource는 @Autowired와 달리 필드 이름으로 빈을 찾는다. 


2. @Qualifier - 추가구분자

  • @Qualifier는 추가 구분자를 붙여주는 방법이다. 주입시 추가적인 방법을 제공하는 것이지 빈 이름을 변경하는 것은 아니다. 
    1. 빈 등록시 @Qualifier를 붙여 준다. 
    2. 주입시에 @Qualifier를 붙여주고 등록한 이름을 적어준다.
    3. 해당 @Qualifier가 붙은 빈을 조회한다.
    4. @Qualifier가 붙은 빈을 못찾으면 필드 또는 파라미터 이름으로 매칭을 시도한다.
    5. 그래도 찾지 못할 경우 NoSuchBeanDefinitionException이 발생한다. 
 @Component
  @Qualifier("mainDiscountPolicy")
  public class RateDiscountPolicy implements DiscountPolicy {}
 @Autowired
  public OrderServiceImpl(MemberRepository memberRepository,
                          @Qualifier("mainDiscountPolicy") DiscountPolicy
  discountPolicy) {
      this.memberRepository = memberRepository;
      this.discountPolicy = discountPolicy;
}

2. @Primary - 빈의 우선순위 부여 

  • @Primary는 우선순위를 정하는 방법이다. @Autowired시에 여러 빈이 매칭되면 @Primary가 우선권을 가진다. 
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {}
  
@Component
public class FixDiscountPolicy implements DiscountPolicy {}

위와 같은 코드의 경우 rateDiscountPolicy가 주입된다. 


@Primary, @Qualifier 활용
  • 코드에서 자주 사용하는 메인 데이터베이스의 커넥션을 획득하는 스프링빈에서는 Primary가 코드도 간결하고 편리하게 조회할 수 있다.
  • 코드에서 특별한 기능으로 가끔 사용하는 서브 데이터베이스의 커넥션을 획득하는 스프링빈에서는 @Qualifier를 지정해서 명시적으로 획득하는 방식이 코드를 깔끔하게 유지할 수 있다. 
우선순위
  • 스프링은 자동보아는 수동이, 넓은 범위의 선택권보다는 좁은 범위의 선택권이 우선 순위가 높다.
  • @Primary는 기본값처럼 동작하는 것이고, @Qualifier는 매우 상세하게 동작한다.
  • 따라서 @Qualifier가 우선권이 높다. 

 

 

출저

인프런 강의 스프링 핵심 원리 - 기본편 (김영한 강사님)

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8