에러 내역을 요약하면 아래와 같다.

1. Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name ' memoryMemberRepository ' defined in class path resource [hello/core/AutoAppConfig.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=autoAppConfig; factoryMethodName=memberRepository; initMethodNames=null; destroyMethodNames=[(inferred)]; defined in class path resource [hello/core/AutoAppConfig.class]] for bean 'memoryMemberRepository' since there is already [Generic bean: class [hello.core.member.MemoryMemberRepository]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodNames=null; destroyMethodNames=null; defined in file [/Users/eunchan/Documents/study/core/out/production/classes/hello/core/member/MemoryMemberRepository.class]] bound.

이 에러 메시지는 memoryMemberRepository라는 이름의 빈이 두 번 정의 되어 있어서 발생한 것이다.

하나는 hello/core/ AutoAppConfig.class 에서, 다른 하나는 hello/core/member/ MemoryMemberRepository.class 에서 정의된 것이다.

스프링은 동일한 이름의 빈을 두 번 정의할 수 없기 때문에 BeanDefinitionOverrideException 을 발생시킨다.

AutoAppConfig를 열어보니 @Bean(name = "memoryMemberRepository")로 정의 되어 있었다.

오류 나는 코드를 주석처리 후 다시 돌려봤다.

이번엔 오류가 두 개 발생했다.

1. Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'memberServiceImpl' defined in file [/Users/eunchan/Documents/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

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. 스프링 부트 3.2에서 발생하는 문제

2. MemberRepository 타입의 빈이 두 개(memoryMemberRepository와 memberRepository) 존재하여, 스프링이 어떤 빈을 주입해야 할지 결정할 수 없어서 발생하는 문제

첫 번째 해결 방법 은 Build, Execution. Deployment -> Build Tools -> Gradle에서

Build and run using과 Run tests using을 Gradle로 변경하면 해결된다.

해결은 됐는데 기존처럼 왼쪽에 어떤 테스트가 통과했는지 목록을 보고 싶어서 두 번째 방법으로 해결했다.

두 번째 해결방법 은 Gradle 설정을 다시 InteliJ로 바꾸고, 명시적으로 주입할 빈을 지정하면 된다.

주입받는 클래스에 ( memoryMemberRepository) @Primary로 명시적으로 지정한다.

package hello.core.member;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
@Primary
public class MemoryMemberRepository implements MemberRepository{
    private static Map<Long, Member> store = new HashMap<>();
    @Override
    public void save(Member member) {
        store.put(member.getId(), member);
    @Override
    public Member findById(Long memberId) {
        return store.get(memberId);

이제 돌려보면??

또 에러가 났다. 

No qualifying bean of type 'hello.core.discount.DiscountPolicy' available: expected single matching bean but found 

2: rateDiscountPolicy,discountPolicy

DiscountPolicy도 명시적으로 지정해 준다.

package hello.core.discount;
import hello.core.member.Grade;
import hello.core.member.Member;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy{
    private int discountPercent = 10;
    @Override
    public int discount(Member member, int price) {
        if (member.getGrade() == Grade.VIP) {
            return price * discountPercent / 100;
        else{
            return 0;

이제 다시 돌려보면?!?!

[Spring error] Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception  (0) 2024.07.01