당니의 개발자 스토리
조회 빈이 2개 이상 - 문제 본문
조회 빈이 2개 이상 - 문제
이번 시간에는 조회할 빈이 2개 이상인 문제에 대해서 알아보겠습니다.

@Autowired는 타입으로 조회를 한단 말이에요.
사실 @RequiredArgsConstructor에 의해서

final이 붙은 두 필드가 자동주입이 된다고 했습니다. @RequiredArgsConstructor에 의해서 생성자가 만들어져서, final 붙은 애들이 자동으로 의존관계 주입이 된다고 했죠.
조금 더 쉽게 설명드리기 위해서, @RequiredArgsConstructor를 빼고 생성자를 다시 만들게요.

@Autowired를 하면, 생성자 파라미터로 들어가는 discountPolicy가 타입으로 조회되거든요.

스프링 컨테이너 안에서 Type으로 조회하기 때문에 ac.getBean(DiscountPolicy.class)와 유사해요.

스프링 빈 조회에서 학습했듯이 타입으로 조회하면, 선택된 빈이 2개 이상일 때 문제가 발생하잖아요.
DiscountPolicy 의 하위 타입인 FixDiscountPolicy , RateDiscountPolicy 둘다 스프링 빈으로 선언해볼게요.
그 전에 테스트 돌려보면, 오류가 발생하는데

다시 주석을 원래대로 해주면 됩니다. 다시 돌려보면 모든 테스트가 성공했습니다. 이렇게 테스트를 돌려보고 나서 코드를 수정해야 됩니다. 실무에서는 Git으로 코드를 받으면 무조건 먼저 테스트를 돌립니다.
다시 돌아가서, FixDiscountPolicy , RateDiscountPolicy 둘다 스프링 빈으로 등록해볼게요.
우리가 RateDiscountPolicy는 이전에

컴포넌트 스캔으로 등록했습니다. 그러면 빈 이름이 rateDiscountPolicy로 올라가겠죠.
FixDiscountPolicy도 컴포넌트 스캔으로 등록해보겠습니다.

이러면 빈 이름이 fixDiscountPolicy로 올라가고, 둘 다 스프링 빈으로 등록이 됐습니다.
이렇게 하고나서 테스트를 다시 돌려보면, 문제가 생길 겁니다.

basicScan()에서 문제가 생겼는데,

빈 하나만 매칭이 되길 바랐는데, 두 개가 찾아졌다는 뜻이에요.

여기서 터진거죠. 의존관계를 주입하려고 보니까 2개가 찾아진 거예요.

그래서 이렇게 의존관계 자동 주입을 실행하면 NoUniqueBeanDefinitionException이 터지는 거죠.
그런데 오류메시지가 친절하게도 하나의 빈을 기대했는데 fixDiscountPolicy, rateDiscountPolicy 2개가 발견되었다고 알려줍니다.

이때 하위 타입으로 지정할 수도 있지만, 하위 타입으로 지정하는 것은 DIP를 위배하고 유연성이 떨어지죠. 왜냐면 하위타입으로 고정이 되면, 역할과 구현에서 역할에 의존해야지 구체적인 것에 의존하면 안 된다고 그랬는데, 이러면 DIP를 어긋나는 거잖아요.
그리고 이름만 다르고, 완전히 똑같은 타입의 자식이 여러 개 있는 경우, 여전히 스프링 빈이 2개 있을 때 해결이 안 돼요.
물론 수동으로 등록해서 문제를 해결할 수도 있어요. 하지만 자동 의존관계 주입에서도 해결할 수 있는 방법이 여러 개가 있습니다.
그 방법들을 다음 시간에 쭉 설명을 드리겠습니다.
'스프링 > 스프링 핵심 원리 - 기본편' 카테고리의 다른 글
| 애노테이션 직접 만들기 (0) | 2024.01.25 |
|---|---|
| @Autowired 필드 명, @Qualifier, @Primary (0) | 2024.01.24 |
| 롬복과 최신 트랜드 (0) | 2024.01.24 |
| 생성자 주입을 선택해라! (0) | 2024.01.24 |
| 옵션 처리 (0) | 2024.01.24 |