스프링 빈 등록시 애노테이션만 달아놓으면 찾아서 자동으로 등록해줬으면 좋겠는데?

지금까지 스프링 빈을 등록할 때, 자바 코드의 @Bean 이나 XML의 <'bean'> 등을 통해서 설정 정보에 직접 등록할 스프링 빈을 나열하는 방법을 사용했습니다.

이렇게 등록해야 할 스프링 빈이 수십, 수백개라면? 첫 문장과 같은 니즈가 생기게 될 것입니다.

@ComponentScan

  • 설정 정보가 없이도 스프링 빈을 등록하는 컴포넌트 스캔이라는 기능을 제공합니다.
    • 또한 의존관계도 자동으로 주입하는 @Autowired 라는 기능도 제공
  • 컴포넌트 스캔은 이름 그대로 @Component 애노테이션이 붙은 클래스를 스캔해서 빈으로 등록해줍니다.

AppConfig → ComponentScan

  • 이전의 AppConfig 에서는 @Bean 으로 직접 설정 정보를 작성했고, 의존관계도 직접 명시했습니다.
    • 이제는 이런 설정 정보 자체가 없기 때문에, 의존관계 주입도 이 클래스 안에서 해결해야 한다.

Autowired

생성자에 @Autowired 를 지정하면, 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입해줍니다.
참고 : 최근에는 Autowired 보다 생성자 주입방식이 권장되고 있습니다.

  • @Autowired는 의존관계를 자동으로 주입해줍니다.
    • 생성자에서 여러 의존관계를 주입해준다.
  • 타입이 같은 빈을 찾아서 주입합니다.
    • ex) getBean(MemberRepository.class)
  • 생성자에 파리미터가 많아도 다 찾아서 자동으로 주입합니다.

Bean Name

  • @ComponantScan@Component 가 붙은 모든 클래스를 스프링 빈으로 등록합니다.
  • 이때 스프링 빈의 기본 이름은 클래스명을 사용하되 맨 앞글자만 소문자를 사용합니다.
    • 빈 이름 기본 전략 : MemberServiceImpl → memberServiceImpl
    • 빈 이름 직접 지정 : @Component(”memberService2”)

탐색 위치와 기본 스캔 대상

탐색할 패키지의 시작 위치 지정

모든 자바 클래스를 다 컴포넌트 스캔하면 시간이 오래걸립니다. 따라서 꼭 필요한 위치부터 탐색하도록 시작 위치를 지정할 수 있습니다.

  • @ComponentScan (basePackages = com.example….)
    • 이 패키지를 포함해서 하위 패키지를 모두 탐색
  • 지정하지 않는다면(Default)?
    • 클래스의 패키지의 하위폴더를 모두 탐색

권장하는 방법

  • 설정 정보 클래스의 위치를 프로젝트의 최상단에 두는 것입니다.
    • 최근의 스프링부트도 이 방법을 사용하고 있다.
    • @SpringBootApplication (@ComponentScan 포함됨)

컴포넌트 스캔 기본 대상

  • @Component : 컴포넌트 스캔에서 사용
  • @Controller : 스프링 MVC 컨트롤러
    • MVC 컨트롤러로 인식
  • @Service : 스프링 비즈니스 로직
    • 특별한 처리X, 개발자들이 핵심 비즈니스 로직이라고 인식
  • @Repository : 데이터 접근 계층
    • 스프링 데이터 접근 계층으로 인식하고, 데이터 계층의 예외를 스프링 예외로 변환해준다.
  • @Configuration : 스프링 설정 정보에서 사용
  • 참고 : useDefaultFilters 옵션은 기본으로 켜져 있습니다. (끄면 기본 스캔 대상이 제외된다.)

애노테이션에는 상속관계라는 것이 없다.

이렇게 애노테이션을 들고 있는 것을 인식할 수 있는 것은 자바 언어가 지원하는 기능이 아니고, 스프링이 지원하는 기능입니다.


필터

  • includeFilter : 컴포넌트 스캔 대상을 추가로 지정합니다.
  • excludeFilter : 컴포넌트 스캔에서 제외할 대상을 지정합니다.
@Configuration
@ComponentScan(
			includeFilters = @Filter(type = FilterType.ANNOTATION, classes = 
MyIncludedComponent.class),
			excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = 
MyExcludedCompnent.class)
  • ex) MyIncludedComponent 애노테이션이 붙은 클래스는 컴포넌트 스캔에서 추가 지정한다.
  • ex) MyExcludedComponent 애노테이션이 붙은 클래스는 컴포넌트 스캔에서 제외 한다.

Filter Type 옵션

  • ANNOTATION : 기본
  • ASSIGNABLE_TYPE : 지정한 타입과 자식 타입을 인식해서 동작
  • ASPECTJ : AspectJ 패턴
  • REGEX : 정규표현식
  • CUSTOM : TypeFilter 이라는 인터페이스를 구현해서 처리

최근 스프링 부트컴포넌트 스캔을 기본으로 제공, 스프링의 기본 설정에 최대한 맞추어 사용하는 것을 권장하고 선호합니다.


Reference.

  • 스프링 핵심 원리 기본편 (김영한님)
profile
ProblemOverFlow

0개의 댓글

Powered by GraphCDN, the GraphQL CDN