인프런 커뮤니티 질문&답변

사사사님의 프로필 이미지

작성한 질문수

스프링 핵심 원리 - 기본편

[섹션 7-5] 같은 타입의 빈이 2개일 때 문제

해결된 질문

작성

·

178

·

수정됨

1

[문제 상황]

이전에는 컴포넌트 스캔의 대상으로 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

 


[질문 사항]

 

  1. @Autowired 매칭을 할 때 필드명, 파라미터 명으로 매칭 되어야하는데 왜 이름을 바꿨는데도 매칭이 안될까요??

     

  2. AutoAppConfig의 오류는 Discount 타입을 임의로 두 개 설정해줘서 발생한 것이지만

     

    CoreApplicationTests는 왜 오류가 발생한 걸까요?


    제 생각엔 수동으로 빈을 등록해주는 코드가 실행돼서 수동 빈들이 등록된 것같은데


    AutoAppConfig 클래스에서 @Configuration 어노테이션이 있으면 빈으로 등록되지 않게 필터도 설정했고, 테스트를 진행하며 작성한 코드도 모두 지워줬는데 왜 memberRepository가 빈으로 등록 되었을 까요?

 

 

 

답변 1

0

안녕하세요. 사사사님, 공식 서포터즈 OMG입니다.

스프링부트 3.2의 오류로 예상이 되는데요, 다음 링크(클릭)을 참고해보시겠어요?

 

감사합니다.

사사사님의 프로필 이미지
사사사
질문자

해결 방안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 을 사용해서 해결했습니다!!