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

윤승제님의 프로필 이미지
윤승제

작성한 질문수

스프링 핵심 원리 - 기본편

@Autowired 필드 명, @Qualifier, @Primary

org.springframework.beans.factory.UnsatisfiedDependencyException

해결된 질문

작성

·

1.4K

0

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

[질문 내용]
section7 @Autowired 필드 명, @Qualifier, @Primary의 약 2:16초

강의의 내용대로 아래의 코드를

public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy)

 

 

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

 

이렇게 바꿔주었지만

AutoAppConfigTest > basicScan()에서

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderServiceImpl' defined in file [/Users/dani/Desktop/dani/practice-spring/spring-basic/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:16)

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

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

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

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

오류가 났습니다.

 

그래서 https://docs.google.com/document/d/1j0jcJ9EoXMGzwAA2H0b9TOvRtpwlxI5Dtn3sRtuXQas/edit#heading=h.b1yk4ued1pxo

이 문서의 해결방안3대로 해보았더니

BeanDefinitionTest > 빈 설정 메타정보 확인

XmlAppContext > xmlAppContext()에서

 

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderService' defined in class path resource [appConfig.xml]: Unsatisfied dependency expressed through constructor parameter 1: Ambiguous argument values for parameter of type [hello.core.discount.DiscountPolicy] - did you specify the correct bean references as arguments?

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

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.support.GenericXmlApplicationContext.<init>(GenericXmlApplicationContext.java:71)

at hello.core.beandefinition.BeanDefinitionTest.<init>(BeanDefinitionTest.java:13)

at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)

at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)

at java.base/java.util.Optional.orElseGet(Optional.java:364)

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

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

같은 오류가 발생하였습니다.

어떻게 해결하면 될까요?

 

아래는 저의 코드입니다.

package hello.core;
import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.MemberRepository;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public MemberService memberService() {
        System.out.println("call AppConfig.memberService");
        return new MemberServiceImpl(memberRepository());
    }
    @Bean
    public MemberRepository memberRepository() {
        System.out.println("call AppConfig.memberRepository");
        return new MemoryMemberRepository();
    }
    @Bean
    public OrderService orderService() {
        System.out.println("call AppConfig.orderService");
        return new OrderServiceImpl(memberRepository(), discountPolicy());
//        return null;
    }
    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }
}

 

package hello.core.order;

import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
import hello.core.member.MemoryMemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
//@RequiredArgsConstructor //생성자 만들어줌
public class OrderServiceImpl implements OrderService {
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy; //추상화인 인터페이스에 의존

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

    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {
        Member member = memberRepository.findById(memberId);
        int discountPrice = discountPolicy.discount(member, itemPrice);

        return new Order(memberId, itemName, itemPrice, discountPrice);
    }

    //테스트 용도
    public MemberRepository getMemberRepository() {
        return memberRepository;
    }
}

 

 

 

 

 

 

 

+) 방법2도 추가로 실행해보았으나 같은 결과가 떴습니다.

답변 3

1

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

해결방안3을 잘 적용하신 것 같고, 추가적인 문제는 코드 오타로 보이네요 😀

다음은 오류 메시지 중 원인에 해당하는 내용인데,

image

작성하신 코드가 강의와 차이가 있습니다.

파라미터의 이름rateDiscountPolicy에서 discountPolicy로 변경하여 확인해주세요 😀

작성하신 코드

image

강의코드

image

 

감사합니다.

윤승제님의 프로필 이미지
윤승제
질문자

제가 들은 부분은

@Autowired 필드 명, discountPolicy에서 rateDiscountPolicy으로 변경하는 부분이었습니다.

답변 감사드립니다.!

image강의에서도 rateDiscountPolicy로 변경했을 때 질문에서 남기신 것과 같이 UnsatisfiedDependecyException 이 발생하고, 발생 원인과 해결방안을 뒤에서 설명해주고 계십니다.

@Autowired 필드 명, @Qualifier, @Primary

강의 초반 부분만 수강하셨다면 끝까지 들어보시면 될 것 같고,

제가 질문을 잘 이해하지 못하였다면 부연설명을 남겨주세요.

(강의 영상을 다 수강하셨는지, appConfig.xml과 관련된 이슈일 수 있으니 해당 xml 파일 전체, 강의 뒷 부분과도 연관지어서 등)

 

질문 발췌

image

윤승제님의 프로필 이미지
윤승제
질문자

말씀대로 찾아보니 appConfig.xml을 수정하지 않아 생긴 문제였습니다ㅜㅜ

친절한 답변 감사드립니다.

0

안녕하세요. 윤승제님, 공식 서포터즈 y2gcoder입니다.

도움을 드리고 싶지만 질문 내용만으로는 답변을 드리기 어렵습니다.

실제 동작하는 전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.

구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx


주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요


추가로 다음 내용도 코멘트 부탁드립니다.

1. 문제 영역을 실행할 수 있는 방법

2. 문제가 어떻게 나타나는지에 대한 상세한 설명


링크: 공식 서포터즈

링크: 자주하는 질문

감사합니다.

윤승제님의 프로필 이미지
윤승제
질문자

https://drive.google.com/file/d/1STl9OJXY23BpAzy7Pcr5obAKnJV7r-57/view?usp=drive_link


1. test 폴더를 전체 실행해주었습니다.

2.

OrderServiceImpl >>

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

이 코드를 실행하면

image

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderServiceImpl' defined in file [/Users/dani/Desktop/dani/practice-spring/spring-basic/core/build/classes/java/main/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

 

 

이러한 에러가 발생하여서 강사님께서

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

 

이렇게 바꿔주라고 하셨습니다.

이렇게 바꿔주면 전체 테스트를 실행하였을 때 모두 통과가 되어야 하는데, 저는

image

 

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderService' defined in class path resource [appConfig.xml]: Unsatisfied dependency expressed through constructor parameter 1: Ambiguous argument values for parameter of type [hello.core.discount.DiscountPolicy] - did you specify the correct bean references as arguments?

 

이러한 에러로 바뀌었습니다.

 

 

윤승제님의 프로필 이미지
윤승제
질문자

해결하였습니다. 친절한 답변 감사드립니다!

0

저랑 똑같으네요

윤승제님의 프로필 이미지
윤승제
질문자

저는 ~3:28까지 들었었는데, 전체 test를 돌려서 발생한 오류였습니다.(강사님은 AutoAppConfigTest만 돌리심)

혹시 몰라 댓글 남깁니다!

윤승제님의 프로필 이미지
윤승제

작성한 질문수

질문하기