에러 내역을 요약하면 아래와 같다.
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