탐색 위치와 기본 스캔 대상
탐색 위치
스캔 대상
@Component
@Controller
@Service
@Repository
@Configuration
이 어노테이션들은 스캔 용도 뿐만 아니라 부가기능을 수행함
- Controller : 스프링 MVC 컨트롤러로 인식
- Repository : 스프링 데이터 접근 계층으로 인식, 데이터계층에서 발생하는 예외를 스프링 예외로 변환해줌
- Configuration : 스프링 설정 정보로 인식, 스프링 빈이 싱글톤을 유지하도록 추가 처리를함
- Service : 특별한 처리를 하진 않음. 다만 개발자들이 아 여기에 비즈니스 로직들이 있겠구나라고 인식하는데 도움을 줌.
- useDefaultFilters라는 옵션이 기본적으로 켜져있는데, 이거끄면 기본스캔 대상들이 제외됨. 그냥 알아만 두기
필터
- 컴포넌트 스캔에서 스캔되는 필터와 아닌 필터, 두가지 annotation을 만듦
- 두 annotation을 각각 붙인 beanA와 beanB를 만듦
- 테스트 코드를 짜서 스캔되는 필터는 include하고, 스캔되지않았으면 하는 필터는 exclude를 하고 돌려보면, beanA는 스캔이되는데, beanB는 찾을 수 없다고 뜸!
@Test
void filterScan() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ComponentFilterAppConfig.class);
BeanA beanA = context.getBean("beanA", BeanA.class);
Assertions.assertThat(beanA).isNotNull();
org.junit.jupiter.api.Assertions.assertThrows(
NoSuchBeanDefinitionException.class,
() -> context.getBean("beanB", BeanB.class));
}
@Configuration
@ComponentScan (includeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class),
excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class))
static class ComponentFilterAppConfig {
}

FilterType 옵션
- ANNOTATION : 기본값, 어노테이션을 인식해서 동작
- ASSIGNABLE_TYPE : 지정한 타입과, 자식타입을 인식해서 동작
- ASPECTJ : AspectJ 패턴 사용
- REGEX : 정규표현식
- CUSTOM : TypeFilter라는 인터페이스를 직접 구현해서 처리하고싶을때
- 사실 실제로 협업에서는 annotation에다가, 뭐...assignable정도까지 사용할 수도 있고, exclude까지는 사용할 수도 있음
- 스프링 기본설정에 최대한 맞춰서 사용하는편이 좋음.
- @Component면 충분하므로 filter사용할 일 없음
중복 등록과 충돌
만약 같은 빈 이름을 등록한다면?
🍀두가지 상황이 존재🍀
1. 자동 빈 등록 vs 자동 빈 등록
2. 수동 빈 등록 vs 자동 빈 등록
수동bean vs 자동bean
- 실제로 test 돌려보면 알아서 spring이 수동으로 오버라이딩함!
- 수동이 이긴다는거임

- 근데 실무에서 이런일이 발생하는 경우? 는 대부분 의도한바가 아니고 걍 설정이 꼬여서 그런거임
- 그래서 spring에서도 최근에는 이런 중복이 발생하는 경우, 그냥 충돌이 나게 만듦
- 지금 충돌이 나지 않은건, 우리가 만든 test라서 그러고, coreApplication 돌리면 오류나는거 볼 수 있음.
꿀팁
- 잡기 어려운 버그는 애매한 버그. 누가봐도 명확한거 말고 애매하게 꼬여서 오류메세지도 안나는 것들 ^^,,,
- 코드가 줄어들고 예뻐지지만 명확하지 못한, 어설픈 추상화 vs 코드가 좀 길고 더럽지만 명확한것 중 하나를 고르면: