챕터 5: 컴포넌트 스캔

binary_j·2023년 9월 30일
0

컴포넌트 스캔이란 스프링이 직접 클래스를 검색해서 빈으로 등록해주는 기능이다. 설정 클래스에서 빈으로 등록하지 않아도 원하는 클래스를 빈으로 등록할 수 있다.

@Component 애노테이션으로 스캔 대상 지정


@Component 애노테이션을 붙이면 해당 클래스를 스캔 대상으로 표시한다.

이 때 애노테이션에 속성값을 줄 수도 있다.

@Component("infoPrinter")

속성값을 주면 빈으로 등록할 때 사용할 이름을 지정할 수 있다. 속성값을 따로 설정하지 않으면 클래스 이름의 첫 글자를 소문자로 바꾼 이름을 빈 이름으로 사용한다.

@ComponentScan 애노테이션으로 스캔 설정


@Component 애노테이션을 붙인 클래스를 스캔해서 스프링 빈으로 등록하려면 설정 클래스에 @ComponentScan 애노테이션을 적용해야 한다.

@ComponentScan(basePackages = {"spring"})

여기서 basePackages 속성값은 스캔 대상 패키지 목록을 지정할 때 사용되는 속성값이다.

스캔 대상에서 제외하거나 포함하기


특정 대상을 스캔 대상에서 제외하고 싶다면 excludeFilters 속성을 사용할 수 있다.

excludFilters 속성은 다음과 같이 지정할 수 있다.

@ComponentScan(basePackages = {"spring"},
	excludeFilters = @Filter(type = FilterType.REGEX, 
    	pattern = "spring\\..*Dao"))

excludeFilters 안에서 @Filter 애노테이션의 type 속성값으로 정규표현식을 지정했다. 위의 코드를 적용하면 spring으로 시작하여 Dao로 끝나는 클래스는 컴포넌트 스캔 대상에서 제외된다.

이 외에도 특정 애노테이션을 붙인 타입을 컴포넌트 대상에서 제외할 수도 있다.

@ComponentScan(basePacakges = {"spring", "spring2"},
	excludeFilters = @Filter(type = FilterType.ANNOTATION,
    	classes = {NoProduct.class, ManualBean.class}))

특정 타입이나 그 하위 타입을 제외하려면 ASSIGNABLE_TYPE을 FilterType으로 사용하면 된다.

@ComponentScan(basePacakges = {"spring"},
	excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE,
    	classes = MemberDao.class))

필터를 여러 개 지정하는 것도 가능하다.

@ComponentScan(basePacakges = {"spring"},
	excludeFilters = {
    	@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MemberDao.class),
        @Filter(type = FilterType.REGEX, pattern = "spring\\..*Dao")
})

찾아보니 FilterType.CUSTOM을 통해 제외하고 싶은 패턴을 직접 지정할 수도 있었다.

https://www.baeldung.com/spring-componentscan-filter-type

스프링의 기본 스캔 대상


@Componenet 애노테이션을 붙인 클래스만 컴포넌트 스캔 대상에 포함되는 것은 아니다. 다음 애노테이션을 붙인 클래스는 모두 컴포넌트 스캔 대상에 포함된다.

  • @Component
  • @Controller
  • @Service
  • @Repository
  • @Aspect
  • @Configuration

여기서 @Aspect를 제외한 나머지 애노테이션은 @Component 애노테이션에 몇 가지 기능이 추가된 특수 애노테이션이다.

컴포넌트 스캔에 따른 충돌 처리


컴포넌트 스캔을 통해 자동으로 빈을 등록할 때 충돌이 발생할 수 있다.

먼저 동일한 빈 이름을 사용하여 빈 이름 충돌이 발생하는 경우 BeanDefinitionStoreException 익셉션이 발생한다. 이를 해결하기 위해 속성값을 사용하여 명시적으로 빈 이름을 서로 다르게 설정해 줄 수 있다.

다음으로 수동 등록한 빈과 충돌이 발생할 수 있다. 스캔할 때 사용하는 빈 이름과 수동 등록한 빈 이름이 같은 경우 수동 등록한 빈이 우선된다.

0개의 댓글