[스프링 기본] 컴포넌트 스캔(2)

마코레·2022년 6월 23일
0

백엔드개발

목록 보기
18/18

탐색 위치와 기본 스캔 대상


탐색 위치

  • 탐색 package 시작 위치를 지정할 수 있음
    • @ComponentScan안에 basePackages를 적어줄 수 있음.
    • 거기서부터 탐색해가게됨! 이게 없으면 spring 내의 모든 폴더를 탐색하면서 bean을 찾기때문에 굉장히 오래걸림.
    • ex)
    @ComponentScan(
            basePackages = "section6.shopBeanAuto.member"
    )
  • 개인적으로 추천하는 방법은 패키지 위치를 지정하지 않고, 설정 정보 클래스의 위치를 프로젝트 최상단에 두는것
  • spring boot도 이 방법을 기본적으로 제공

스캔 대상

@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 옵션

  1. ANNOTATION : 기본값, 어노테이션을 인식해서 동작
  2. ASSIGNABLE_TYPE : 지정한 타입과, 자식타입을 인식해서 동작
  3. ASPECTJ : AspectJ 패턴 사용
  4. REGEX : 정규표현식
  5. CUSTOM : TypeFilter라는 인터페이스를 직접 구현해서 처리하고싶을때
  • 사실 실제로 협업에서는 annotation에다가, 뭐...assignable정도까지 사용할 수도 있고, exclude까지는 사용할 수도 있음
  • 스프링 기본설정에 최대한 맞춰서 사용하는편이 좋음.
  • @Component면 충분하므로 filter사용할 일 없음


중복 등록과 충돌


만약 같은 빈 이름을 등록한다면?

🍀두가지 상황이 존재🍀
1. 자동 빈 등록 vs 자동 빈 등록
2. 수동 빈 등록 vs 자동 빈 등록

수동bean vs 자동bean

  • 실제로 test 돌려보면 알아서 spring이 수동으로 오버라이딩함!
  • 수동이 이긴다는거임
  • 근데 실무에서 이런일이 발생하는 경우? 는 대부분 의도한바가 아니고 걍 설정이 꼬여서 그런거임
  • 그래서 spring에서도 최근에는 이런 중복이 발생하는 경우, 그냥 충돌이 나게 만듦
  • 지금 충돌이 나지 않은건, 우리가 만든 test라서 그러고, coreApplication 돌리면 오류나는거 볼 수 있음.

꿀팁

  • 잡기 어려운 버그는 애매한 버그. 누가봐도 명확한거 말고 애매하게 꼬여서 오류메세지도 안나는 것들 ^^,,,
  • 코드가 줄어들고 예뻐지지만 명확하지 못한, 어설픈 추상화 vs 코드가 좀 길고 더럽지만 명확한것 중 하나를 고르면:
    • 명확한 쪽이 훨씬 이득
profile
새싹 백엔드 개발자

0개의 댓글