컴포넌트 스캔(ComponentScan)

2023. 5. 3. 14:04JAVA/Spring

목차

  • 컴포넌트 스캔의 필요성
  • 컨포넌트 스캔 예시
  • excludeFilters
  • basePackages
  • basePackageClasses

 

컴포넌트 스캔(ComponentScan)

컴포넌트 스캔은 클래스를 탐색하며 @Component 애노테이션이 붙은 클래스를 스프링 빈으로 등록하는 기능입니다.

 

컴포넌트 스캔의 필요성

컴포넌트 스캔이 필요한 이유는 기존 @Bean을 통해서 수동적으로 스프링 빈을 등록하였지만, 등록할 빈 개수가 증가할수록 관리가 어려워집니다. 따라서 이러한 빈 등록을 자동적으로 해야할 필요성이 있습니다.

 

컴포넌트 스캔을 사용하지 않고 기존 스프링 빈을 등록하는 대표적인 방법은 @Bean 애노테이션을 사용하는 것입니다. 다음 코드와 같이 @Configuration 애노테이션이 적용된 클래스의 메소드를 정의하여 등록할 스프링 빈을 정의합니다.

@Configuration
public class AppConfig {

    @Bean
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
}

위와 같은 방법으로도 스프링 빈을 등록할 수는 있지만 위와 같은 수동적인 빈 등록이 증가할수록 설정 정보는 커지게되고 설정 정보를 누락하는 문제가 발생할 수 있습니다. 

 

  • 컴포넌트 스캔의 필요성 : 수동적인 빈 등록을 자동적으로 등록할 수 있게 하기 위함입니다.
  • 수동적인 빈 등록의 문제점 : 등록할 스프링 빈 개수가 증가할 수록 설정 정보는 커지게 되고 설정 정보를 누락하는 문제가 발생할 수 있습니다.

 

컴포넌트 스캔의 예시

컴포넌트 스캔을 사용하기 위해서는 @Configuration이 있는 클래스에 사용할 수 있습니다.

 

@Configuration
@ComponentScan
public class AutoAppConfig {
}
  • AutoAppConfig 클래스가 위치한 패키지를 포함 하위 패키지를 탐색하여 스프링 빈으로 등록합니다.
  • 스프링 빈 등록 대상 클래스 : @Component, @Controller, @Service, @Repository, @Configuration이 적용된 클래스
    • @Controoer, @Service, Repository, @Configuration은 내부에 @Component가 적용되어 있는 애노테이션입니다.
    • 즉, 컴포넌트 스캔의 대상 클래스는 @Component가 적용된 클래스입니다.

 

컴포넌트 스캔 옵션 : excludeFilters

컴포넌트 스캔의 옵션 중 하나인 excludeFilters 옵션은 스프링 빈으로 등록하지 않을 대상들을 설정할 수 있습니다.

@Configuration
@ComponentScan(
    excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)
)
public class AutoAppConfig {

}

위와 같이 excludeFilters 옵션에 Filter 타입의 값을 설정하면 필터 대상에 해당하는 클래스는 빈 등록에서 제외할 수 있습니다. 위 예제에서는 Configuration 애노테이션이 적용된 클래스인 경우에는 빈 등록을 제외합니다.

 

컴포넌트 스캔 옵션 : basePackages

컴포넌트 스캔의 옵션 중 하나인 basePackages 옵션은 컴포넌트 스캔을 수행할 특정 패키지 기준을 설정할 수 있습니다. 옵션값으로 패키지 경로를 문자열로 작성하면 해당 패키지를 포함한 하위 패키지를 탐색하여 스프링 빈으로 등록합니다.

 

@Configuration
@ComponentScan(
    basePackages = "hello.core.member"
)
public class AutoAppConfig {
}
  • basePackages = "hello.core.member" : hello/core/member 패키지를 기준으로 member 패키지 포함 하위 패키지를 탐색하여 스프링 빈으로 등록합니다.

위 컴포넌트 스캔의 탐색범위를 그림으로 표현하면 다음과 같습니다.'

 

 위 그림과 같이 hello.core.member 패키지를 기준으로 컴포넌트 스캔시 @Service, @Repository가 적용된 MemberServiceImpl과 MemoryMemberRpository 클래스가 스프링빈으로 등록됩니다.

 

컴포넌트 스캔의 basePackages 필요성

basePackages 옵션을 사용하는 이유는 모든 자바 코드를 탐색하여 스프링 빈으로 등록하는 것이 시간이 많이 걸리기 때문입니다.

 

 

컴포넌트 스캔 옵션 : basePackageClasses

basePackageClasses 옵션은 특정한 클래스를 선택하여 클래스 위치의 패키지를 포함한 하위 패키지를 탐색하여 스프링 빈으로 등록합니다.

 

@Configuration
@ComponentScan(
    basePackageClasses = AutoAppConfig.class
)
public class AutoAppConfig {

}
  • AutoAppConfig가 저장된 hello.core 패키지를 기준으로 컴포넌트 스캔을 수행합니다.

 

컴포넌트 스캔에 아무 옵션도 없다면 어떻게 되는가?

@ComponentScan이 적용된 클래스의 패키지 포함 하위 패키지를 대상으로 컴포넌트 스캔을 수행합니다.

 

컴포넌트 스캔의 Best Practice

옵션으로 패키지를 지정하지 않고 @ComponentScan가 적용된 설정정보 클래스를 프로젝트 "최상단"에 두는 것을 권장합니다. 스프링부트의 경우 이러한 Best Practice를 기본적으로 지원합니다.

 

 

References

스프링 핵심 원리 - 기본편