티스토리 뷰
상황 가정
컴포넌트 스캔에서 같은 빈 이름을 등록하면 어떻게 될까?
다음 두가지 상황이 있다.
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