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

김수환님의 프로필 이미지
김수환

작성한 질문수

스프링 핵심 원리 - 기본편

@Autowired 필드 명, @Qualifier, @Primary

basicScan 실행 시, NoUniqueBeanDefinitionException 발생

작성

·

442

0

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
영한쌤 따라서 @Autowired 필드명 방법을 사용했더니 다음과 같은 에러가 발생했습니다.

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderServiceImpl' defined in file [C:\Program Files\core\core\out\production\classes\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

at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:798)

at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)

at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975)

at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:959)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)

at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:93)

at hello.core.scan.AutoAppConfigTest.basicScan(AutoAppConfigTest.java:14)

at java.base/java.lang.reflect.Method.invoke(Method.java:568)

at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.core.discount.DiscountPolicy' available: expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy

at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:218)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1420)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353)

at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:907)

at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:785)

... 17 more

아래는 제 코드입니다.

에러 내용으로만 봐서는 rateDiscountPolicy와 fixDiscountPolicy 때문에 빈이 2개 등록된다는 것 같은데.. @Autowired 필드명 방법이 그러한 문제를 해결하려는 건데 왜 에러가 날까요ㅠㅠ

답변 2

0

안녕하세요. 김수환님, 공식 서포터즈 David입니다.

아래 답변을 참고해 주세요.

https://www.inflearn.com/questions/1089023/comment/300283

감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다. 김수환님.

NoUniqueBeanDefinitionException 오류는 스프링 컨테이너가 의존성을 주입하려고 할 때 해당 타입의 빈(Bean)이 여러 개 존재하고, 특정 빈을 선택하는 기준이 명확하지 않아 발생하는 문제입니다. 이 경우 스프링은 어떤 빈을 주입해야 하는지 결정하지 못해 예외(오류)를 발생시킵니다.

이 오류는 OrderServiceImpl 클래스에 주입하려는 DiscountPolicy 타입의 빈이 rateDiscountPolicyfixDiscountPolicy 두 개가 등록되어 있는 상태에서 발생하는 것으로 보입니다. @Autowired를 사용할 때 필드명으로 빈을 지정하였음에도 불구하고 오류가 발생하는 경우는, 필드명이 아닌 생성자의 파라미터 명을 사용해야 하는 상황일 수 있습니다.

예를 들어, 아래와 같은 생성자가 있다고 가정할 때:

@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
    // ...
}

discountPolicy 파라미터에 주입될 빈이 명확하지 않습니다. 이를 해결하기 위해, @Qualifier 어노테이션을 사용하거나 @Primary 어노테이션을 통해 우선순위를 지정해야 할 수 있습니다. 또는 필드명이 아니라 생성자 파라미터 명에 맞추어 빈의 이름을 지정해주어야 합니다.

이에 관한 유사한 케이스로 여러 게시물이 있으며, 각 상황에 따른 해결 방법을 참고하실 수 있습니다.

  1. NoUniqueBeanDefinitionException 해결방법 1
  2. NoUniqueBeanDefinitionException 해결방법 2

또한, 생성자 파라미터의 명칭과 @Autowired 필드명이 일치하도록 설정하는 방법이나 @Primary를 사용하는 방법도 고려해볼 수 있습니다. 이와 관련된 강의 내용을 다시 한번 확인해보시는 것도 추천드립니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

김수환님의 프로필 이미지
김수환

작성한 질문수

질문하기