코드 그라데이션

중복 등록과 충돌 본문

Spring/핵심 원리 구현

중복 등록과 충돌

완벽한 장면 2024. 2. 2. 02:41

상황 가정

컴포넌트 스캔에서 같은 빈 이름을 등록하면 어떻게 될까?

다음 두가지 상황이 있다.

 

1. 자동 빈 등록 vs 자동 빈 등록

2. 수동 빈 등록 vs 자동 빈 등록

 

1. 자동 빈 등록 vs 자동 빈 등록

컴포넌트 스캔에 의해 자동으로 스프링 빈이 등록되는데, 그 이름이 같은 경우 스프링은 오류를 발생시킨다.

=> `ConflictingBeanDefinitionException` 예외 발생

 

실행

@Component("service") // 여기
public class MemberServiceImpl implements MemberService { }
@Component("service") // 여기 중복
public class OrderServiceImpl implements OrderService { }

 

class AutoAppConfigTest {
    // 이름 중복 만들어놓고 돌리기
    @Test
    void basicScan() {
        ApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);
        MemberService memberService = ac.getBean(MemberService.class);
        assertThat(memberService).isInstanceOf(MemberService.class);
    }
}

이거 다시 돌려보면

이 에러 나옴.

 

다시 원상복구

 


수동 빈 등록 vs 자동 빈 등록

만약 수동 빈 등록과 자동 빈 등록에서 빈 이름이 충돌되면 어떻게 될까?

1)

@Component
public class MemoryMemberRepository implements MemberRepository { }

 

2) 

@Configuration //설정 정보
@ComponentScan( // @Component 붙은 자동으로 컴포넌트 정보들을 끌어오는 것
        excludeFilters = @Filter(type = FilterType.ANNOTATION, // 그 중에서 뺄 것 @Bean붙은건 수동으로 등록해놓은거니까
                                 classes = Configuration.class)
)
public class AutoAppConfig {

    @Bean(name = "memoryMemberRepository") // 수동 빈 등록
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

}

 

이 경우 수동 빈 등록우선권을 가진다.

(수동 빈이 자동 빈을 오버라이딩 해버린다.)

 

수동 빈 등록 시 남는 로그

전체 로그

Overriding bean definition for bean 'memoryMemberRepository' with a different definition: replacing [Generic bean: class [inflearn.spring_core.member.MemoryMemberRepository]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [C:\Inflearn_Spring\spring_core\out\production\classes\inflearn\spring_core\member\MemoryMemberRepository.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=autoAppConfig; factoryMethodName=memberRepository; initMethodName=null; destroyMethodName=(inferred); defined in inflearn.spring_core.AutoAppConfig]

 

 

SpringCoreApplication 실행

아, 참고로 @SpringBootApplication 눌러보면

 

2023-10-10 01:56:50.183 ERROR 10480 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

The bean 'memoryMemberRepository', 
defined in class path resource [inflearn/spring_core/AutoAppConfig.class], 
could not be registered. A bean with that name has already been defined in file 
[C:\Inflearn_Spring\spring_core\out\production\classes\inflearn\spring_core\member\MemoryMemberRepository.class] 
and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding 
by setting spring.main.allow-bean-definition-overriding=true // 이게 방법!


Process finished with exit code 1

 

application.properties 들어가서 코드를 추가하자.

spring.main.allow-bean-definition-overriding=true

 

실행하면

 

에러가 사라진다!

728x90

'Spring > 핵심 원리 구현' 카테고리의 다른 글

옵션 처리  (0) 2024.02.04
다양한 의존관계 주입 방법  (1) 2024.02.03
필터  (0) 2024.02.01
컴포넌트 스캔 기본 대상  (1) 2024.01.31
탐색 위치  (0) 2024.01.31
Comments