티스토리 뷰

@Autowired를 통해 의존관계를 주입할 때, spring은 type을 통해 적절한 구현체를 찾아 주입해준다. 이때, type이 일치하는 spring bean이 여러 개라면 어떻게 될까?


다음과 같은 error 가 난다.

NoUniqueBeanDefinitionException

하나의 matching을 기대했지만 2개가 matching 된댄다. (참 친절하다..)

 

해결 방법은 세 가지가 있다.

1. 의존관계 주입시 변수명을 주입할 객체와 동일하게 한다.

위와 같이 구현체의 변수명을 특정하면 스프링이 type과 match 되는 것이 여러 개일 경우 변수명을 통해 적절한 구현체를 주입해준다.

하지만 이 방법은 의존관계를 바꿀 때 클라이언트의 코드를 수정하는 것이므로 개방-폐쇄 원칙을 위반한다.

 

2. @Qualifier 

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

...

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

두번째 방법은 구현체에 @Qualifier를 붙이고, 이를 주입할 때도 동일한 @Qualifier를 붙여주는 방식이다.

 

3. @Primary

@Component  
@Primary
public class RateDiscountPolicy implements DiscountPolicy{

...


}
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
}

세번째 방법은 구현체에 @Primary를 붙이는 것이다. 이는 두번째 방법과 달리 의존관계를 주입할 때 annotation을 별도로 붙이지 않아도 되는 장점이 있다.

 

(참고)

@Primary 와 @Qualifier 가 동시에 쓰이면 어떻게 될까? 

이 때는 @Qualifier가 우선순위를 갖는다. spring은 항상 좁은 범위, 프로그래머가 더 자세히 특정한 범위에 우선권을 준다.

 

정리하자면,

@Primary가 @Qualifier보다 편리하므로, @Primary를 우선적으로 쓰되, 사용 빈도가 적고 특수한 케이스(e.g. 보조데이터베이스 커넥션 활용)에 @Qualifier를 붙이는 것이 이상적이다.

 

 

사진, 내용 출처 : 인프런, 김영한 강사님의 '스프링 핵심 원리 - 기본편' 강좌, 강의자료

https://inf.run/TErf

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함