[섹션 7-5] 같은 타입의 빈이 2개일 때 문제
[문제 상황]
이전에는 컴포넌트 스캔의 대상으로 RateDiscountPolicy 만 등록해줬지만, FixDisCountPolicy에 @Component를 추가해서 컴포넌트 스캔의 대상으로 만들어줬습니다.
그래서 같은 타입이 2개 이상일 때 @Autowired를 사용하면 오류가 발생해서 필드명을 빈 이름으로 변경하는 방법을 쓰기 위해 OrderServiceImpl의 코드를 아래와 같이 수정했습니다.
OrderServiceImpl의 코드
@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository,DiscountPolicy rateDiscountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = rateDiscountPolicy;
}
그리고 나서 아래의 테스트를 진행한 결과 ...
AutoAppConfigTest
public class AutoAppConfigTest {
@Test
@DisplayName("컴포넌트 스캔해서 스프링 빈 등록하기")
void basicScan(){
AnnotationConfigApplicationContext ac =
new AnnotationConfigApplicationContext(AutoAppConfig.class);
MemberService memberService = ac.getBean(MemberService.class);
assertThat(memberService).isInstanceOf(MemberService.class);
}
}
AutoAppConfigTest 뿐만 아니라 CoreApplicationTests도 오류가 발생했습니다.

그리고 각각의 오류 메세지는 다음과 같습니다.
AutoAppConfigTest 오류메세지
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'orderServiceImpl' defined in file [...\hello\core\order\OrderServiceImpl.class]:
Unsatisfied dependency expressed through constructor parameter 1:
No qualifying bean of type 'hello.core.discount.DiscountPolicy' available:
expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy
CoreApplicationTests 오류메세지
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'memberServiceImpl' defined in file :
Unsatisfied dependency expressed through constructor parameter 0:
No qualifying bean of type 'hello.core.member.MemberRepository' available:
expected single matching bean but found 2: memoryMemberRepository,memberRepository
OrderServiceImpl 의 코드에서 rateDiscountPolicy로 코드를 수정했음에도 왜 빈을 구분 할 수 없다는 오류가 발생한 것이고 , CoreApplicationTests는 왜 오류가 발생한 것 일까요?
참고로 @Qualifier과 @Primary 를 사용하면 AutoAppConfigTest 는 성공하고
CoreApplicationTests만 실패합니다 !!
아래는 CoreApplicationTests만 실패시 오류 메세지 입니다.
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'hello.core.member.MemberRepository' available:
expected single matching bean but found 2: memoryMemberRepository,memberRepository
[질문 사항]
@Autowired 매칭을 할 때 필드명, 파라미터 명으로 매칭 되어야하는데 왜 이름을 바꿨는데도 매칭이 안될까요??
AutoAppConfig의 오류는 Discount 타입을 임의로 두 개 설정해줘서 발생한 것이지만
CoreApplicationTests는 왜 오류가 발생한 걸까요?
제 생각엔 수동으로 빈을 등록해주는 코드가 실행돼서 수동 빈들이 등록된 것같은데
AutoAppConfig 클래스에서 @Configuration 어노테이션이 있으면 빈으로 등록되지 않게 필터도 설정했고, 테스트를 진행하며 작성한 코드도 모두 지워줬는데 왜 memberRepository가 빈으로 등록 되었을 까요?
답변 1
0
안녕하세요. 사사사님, 공식 서포터즈 OMG입니다.
스프링부트 3.2의 오류로 예상이 되는데요, 다음 링크(클릭)을 참고해보시겠어요?
감사합니다.
3
해결 방안2
컴파일 시점에 -parameters 옵션 적용
1. IntelliJ IDEA에서 File -> Settings를 연다. (Mac은 IntelliJ IDEA -> Settings)
2. Build, Execution, Deployment → Compiler → Java Compiler로 이동한다.
3. Additional command line parameters라는 항목에 다음을 추가한다.
-parameters
4. out 폴더를 삭제하고 다시 실행한다. 꼭 out 폴더를 삭제해야 다시 컴파일이 일어난다.
위의 방법으로 CoreApplicationTests 성공했습니다.
그리고 DiscountPolicy 주입 문제의 경우는 필드명으로는 주입이 안돼서 그냥 @Qualifier 을 사용해서 해결했습니다!!
코드 자료
0
25
2
구현체가 동적으로 정해질 때, 팩토리 기법을 사용하나요?
0
51
2
MemberService의 인터페이스를 왜 사용하는지 궁금합니다.
0
74
1
롬복 @Setter를 써야 하는 상황이 있는건가요?
0
89
1
빈 등록 메서드의 파라미터가 빈이 아니어도 되나요?
0
81
1
테스트 속도가 나중에 영향이 있을까요?
0
77
1
gradle 설정 안떠서 질문 남깁니다!
0
120
2
build.gradle로 프로젝트를 여는 이유
0
85
1
provider 사용하는 이유
0
88
1
다음 강의 뭘 들어야 할까요
0
126
2
프로토타입 빈, 직접 destroy 호출 안 할 경우
0
64
1
beanB
0
82
2
퀴즈다시풀기
0
66
1
Gradle로 바꿔도 오류가 똑같이 발생하네요 ㅠㅠ
0
92
2
"중복 등록과 충돌" 강의에서 강사님과 다른 에러가 발생합니다.
0
65
3
run 실행했는데 결과창이 이렇게 뜨네요 왜 그런건가요>
0
105
2
도메인의 정의?
0
59
1
ApplicationContext 질문입니다.
0
62
1
@Scope의 proxyMode를 사용할때 단위 테스트 방법
0
88
2
ai api 선정하기 관련 질문
0
118
2
생성자 자동주입 관련해서
0
64
1
생성자 직접 호출 vs 팩토리 메서드 패턴
0
96
2
Spring에서 SessionScope와 RequestScope는 함께 사용되나요?
1
65
1
12:25
0
77
2





