m1ndy5's coding blog

UnsatisfiedDependencyException (feat.영한님 강의) 본문

백엔드 with java/spring

UnsatisfiedDependencyException (feat.영한님 강의)

정민됴 2023. 12. 5. 16:37

... 증말 이 문제로 몇시간은 헤맨 것같다,,,ㅎ
문제의 시작부터 차근 차근 따라가보자,,,,
먼저 프로젝트에는 2가지의 @Configuration 파일이 있었다.

package hello.core;

import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDisscountPolicy;
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(){
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public OrderService orderService(){
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }

    @Bean
    public MemberRepository memberRepository(){
        return new MemoryMemberRepository();
    }

    @Bean
    public DiscountPolicy discountPolicy(){
        return new RateDiscountPolicy();
    }

}

수동으로 등록시킨 AppConfig파일과

package hello.core;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

@Configuration
@ComponentScan(
        excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)
)
public class AutoAppConfig {
}

컴포넌트 스캔을 사용해 빈을 등록하는 AutoAppConfig 파일이다.
이 때 AppConfig와 AutoAppConfig 파일의 중복을 막기 위해서 AutoAppConfig에서 @Configuration이 달린 애는 안읽히게 해놨다
즉 AppConfig에 있는 정보들은 빈으로 등록이 안될 것이다!
그리고 나서 모든 테스트를 돌렸는데 이게 웬일 ApplicationTest가 안돌아갔다.
에러메세지는

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'memberServiceImpl' defined in file [/Users/minsung/Desktop/study/core/out/production/classes/hello/core/member/MemberServiceImpl.class]: 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

이거였고 즉 memoryMemberRepository와 memberRepository 둘 다 빈으로 등록되어 있어서 뭘 의존성 주입해야될지 모르겠어요~ 이런뜻이었다.
일단 @Autowired는 type으로 빈을 조회하기 때문에 MemberRepository 타입을 조회했을 것이다.
근데 내가 여기서 아주 큰 착각을 했다.
MemberRepository 인터페이스가 빈으로 만들어졌다고 착각한 것이다.....
여기서 왜 인터페이스가 빈으로 만들어지는지에 대해서만 미친듯이 삽질하면서 검색한듯...ㅋ
그런데 이유는 다름아닌.......
@SpringBootApplication 에 있었다.........ㅋㅋㅋㅋㅋㅋ (일단 내 뇌피셜)
@SpringBootApplication을 까보면

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

이런 어노테이션들을 포함하고 있는데 @ComponentScan도 있다.
생각해보니까 AutoAppConfig에서만 막는다고 AppConfig가 안읽히는게 아니었다;;;
이렇게 문제의 결론은 났지만(아직 안남ㅎ) 덕분에 알게 됐던 지식들도 있다.
여러개의 Component가 등록됐을 때 그중 사용하고 싶은 한개에 @Primary를 붙여주면 @Autowired가 걔를 읽어준다는 것과
@Autowired 대신 @RequiredArgsConstructor을 사용하는 것을 권장하는 것!!
이건 아마 앞으로의 강의에서 설명해주실 것같아서 일단은 그렇구나 정도로 넘어가려고 한다!

추가

@SpringbootApplication 어노테이션 때문이 아닌가 싶기도 한데...

아시는 분 헬프미요ㅠㅜㅠㅜㅠ

일단 https://stackoverflow.com/questions/71399411/how-can-i-exclude-a-specific-configuration-class-from-my-spring-boot-applicatio 이 사람은 나랑 똑같이 생각하는 것 같긴하다..

 

인프런 질문

https://www.inflearn.com/questions/1089023/%ED%95%B4%EA%B2%B0-%EC%95%88-%EB%90%A8-%EC%84%B9%EC%85%98-7-%EC%98%B5%EC%85%98-%EC%B2%98%EB%A6%AC-%EC%A0%84%EC%B2%B4-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%A4%91-coreapplicationtests-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%9D%98-contextloads-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%8B%A4%ED%8C%A8-%EC%A7%88

 

[해결 안 됨] [섹션 7 - 옵션 처리] 전체 테스트 중 CoreApplicationTests 클래스의 contextLoads 테스트 실패

안녕하세요.게시판을 둘러보니 비슷한 오류가 나시는 분들이 계신것 같은데 해결 되신 분이 없는 것 같아 질문드립니다.구글 드라이브 링크 : https://drive.google.com/file/d/1FEwGM1FjqhTLDav8Mde76EzILf-x_FVl/v

www.inflearn.com

답이 달리는 것 보고 업로드해야겠다.