Back-End/Spring

[Spring][스프링 기본편] - 24. 조회 빈이 2개 이상일 때와 해결법(@ Autowired, @Qualifier, @Primary)

얄루몬 2022. 1. 31. 10:52

💻본 포스팅은 '스프링 핵심 원리 - 기본편 김영한'님의 강의를 듣고 작성되었습니다.

 

스프링 핵심 원리 - 기본편 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com


[조회 되는 빈이 2개 이상일 때 - 문제]

인터페이스를 구현하는 구현체가 여러개 일 때 스프링 빈에는 1가지만 등록이 되어야 문제가 생기지 않는다. 

그러나 스프링 빈을 조회했을 때 조회되는 빈이 2개 이상이게 되면 에러가 발생하게 된다. 


이를 해결하기 위해서는 어떻게 해야 할까?

 

[하위 타입 수동 지정]

하위 타입을 지정해주게 되면 DIP(의존 역전 원칙)을 위반하게 된다. 또한 코드의 유연성 역시 떨어져서 추천하지 않는다. 그렇다면 우리는 이를 해결하기 위해서는 어떻게 해야할까?? 

 

 

 

[자동관계 주입에서 해결]

  1. @Autowired
  2. @Qualifier
  3. @Primary

우리는 위의 세가지 방법을 통해서 조회 되는 빈이 2개일 때의 문제를 해결할 수 있다.

 

[@Autowired]

  • 타입 매칭
    • 타입 매칭이 안 될때 필드 명, 파라미터 명으로 빈 이름을 매칭해준다

 

  • 타입 매칭의 결과가 2개 이상일 때 필드 명, 파라미터 명으로 빈 이름 매칭
//필드 명 매칭
Autowired
private DiscountPolicy rateDiscountPolicy

//파라미터 명 매칭은 생성자에 들어간 파라미터 변경을 위와 같이 해주면 된다.

 

 

[@Qualifier]

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

@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {}
@Autowired
public OrderServiceImpl(MemberRepository memberRepository,
 @Qualifier("mainDiscountPolicy") DiscountPolicy 
discountPolicy) {
 this.memberRepository = memberRepository;
 this.discountPolicy = discountPolicy;
}

 

[참고]

직접 빈 등록시에도 사용이 가능하다!

 

[@Primary]

우선순위를 정하는 방식으로 여러 빈이 매칭될 때 우선권을 갖게 해준다.

 

[@Qualifier VS @Primary]

@Qualifier  @Primary
우선권을 갖는다.
(매우 상세하게 동작하고 좁은 범위의 선택권이 우선순위가 높기 때문)
기본값처럼 동작하기 때문에 @Qualifier보다 낮은 우선순위를 갖는다.
주입 받을 때 모든 코드에 @Qualifier를 붙여줘야 한다.(단점) 우선순위가 높은 코드에만 붙여주면 된다.