오늘의하루

Spring ComponentScan 관련 정리 본문

Spring

Spring ComponentScan 관련 정리

오늘의하루_master 2023. 8. 20. 20:10

ComponentScan은 쉽게 말하면 자동으로  빈을 등록하는 기능을 말한다.

 

@ComponentScan은 @Component가 붙은 모든 클래스를 스프링 빈에 등록한다.

  • 이때 등록되는 빈의 이름은 클래스명을 사용하되 앞글자만 소문자로 사용한다.
  • 만약 이름을 변경하고 싶다면 @Component("이름")으로 지정할 수도 있다.
  • 빈객체는 해당 Component가 붙은 클래스가 된다.

생성자에 @Autowired를 지정하면 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입한다.

  • 이때 기본 조회 전략은 타입이 같은 빈을 찾아서 주입한다.
  • 같은 타입이 둘 이상이라면 오류가 발생한다. (해결 가능)
  • 생성자의 매개변수가 부모타입이라면 다형성으로 자식타입을 찾아서 주입한다.

@ComponetScan의 경우 기본적으로 최상단에 두는것이 좋다.

  • 참고로 Spring boot를 사용하면 스프링 부트의 대표 시작 정보인 @SpringApplictaion를 해당 프로젝트 시작 루트 위치에 두는 것이 관례이다. (@SpringApplication 안에는 @ComponentScan이 들어있다.)

@ComponentScan의 옵션

아무것도 적지않으면 해당 클래스가 속한 패키지의 하위를 모두 탐색한다.

  • basePackages : 컴포넌트 스캔을 할 위치를 지정한다.
    • basePackages = "hello.core.member"
    • basePackages = {"hello.core", "hello.service"}
  • basePackageClasses : 지정한 클래스의 패키지를 탐색 시작 위치로 지정한다.
    • basePackageClasses = AppConfig.class
  • excludeFilters : 컴포넌트 스캔시 제외할 것을 지정한다. (반대는 includeFilters)
    • excludeFilters = @ComponentScan.Filter(type=FilterType.ANNOTATION, classes=Configuration.class)
    • @Configuration 어노테이션이 붙은것들은 스캔하지 않을것이다.
    • FilterType 옵션 알아보기
      • 기본적으로 ANNOTATION으로 동작한다.
      • ASSIGNABLE_TYPE : 지정한 타입과 자식 타입을 인식해서 동작한다.
      • ASPECTJ : AspectJ 패턴 사용
      • REGEX : 정규 표현식
      • CUSTOM : TypeFilter라는 인터페이스를 구현해서 처리

@ComponentScan의 기본 스캔 대상

어노테이션은 상속관계가 없으며, 특정 어노테이션이 특정 어노테이션을 들고있다고 인식하는 것은 자바 언어가 지원하는 기능이 아니고 스프링이 지원하는 기능이다.

  • @Component : 컴포넌트 스캔에서 사용
  • @Controller : 스프링 MVC 컨트롤러 
  • @Service : 스프링 비즈니스 로직
  • @Repository : 스프링 데이터 접근 계층
  • @Configuration : 스프링 설정 정보

빈 중복 등록과 충돌

  • 자동 빈 등록 vs 자동 빈 등록 ( 거의 없는 경우)
    • 컴포넌트 스캔에 의해 자동으로 등록되는데 이름이 같은 경우 "ConfictingBeanDefinitionException" 예외 발생
  • 수동 빈 등록 vs 자동 빈 등록
    • 수동빈이 우선권을 갖는다. (수동 빈이 자동 빈을 오버라이딩해버린다.)
    • 하지만 최근 스프링 부트에서는 해당 경우 오버라이딩을 하지만 에러를 발생시킨다.
    • 이유는 어것을 의도적으로 한것인지 아닌지 모르기 때문이다.
    • 만약 의도적이였다면 application.properties파일에 bean-definition-overriding=true을 입력해줘야 한다.
    • 디폴트 값은 false이다.
Comments