1. 개요

이 튜토리얼에서는 Spring의 컴포넌트 스캐닝을 다룰 것입니다. Spring으로 작업 할 때 클래스를 Spring Bean으로 만들기 위해 클래스에 어노테이션을 달 수 있습니다. 그러나 그 외에도 어노테이션이 달린 클래스를 검색 할 위치를 Spring에 알릴 수 있습니다 .이 특정 실행에서 모든 클래스 가 Bean이되어야하는 것은 아닙니다.

물론 구성 요소 스캔에 대한 몇 가지 기본값이 있지만 검색을 위해 패키지를 사용자 정의 할 수도 있습니다.

먼저 기본 설정을 살펴 보겠습니다.

2. 인수없는 @ComponentScan

2.1. Spring 애플리케이션에서 @ComponentScan 사용

Spring과 함께, 우리는 사용  @ComponentScan 와 함께 어노테이션을 @Configuration의 우리가 스캔하려는 패키지를 지정하는 어노테이션 . 인수가없는 @ComponentScan 은 Spring에 현재 패키지와 모든 하위 패키지를 스캔하도록 지시합니다.

이제 우리는 다음 있다고 가정 해 봅시다 @Configuration 에서  com.baeldung.componentscan.springapp의  패키지를 :

@Configuration
@ComponentScan
public class SpringComponentScanApp {
    private static ApplicationContext applicationContext;

    @Bean
    public ExampleBean exampleBean() {
        return new ExampleBean();
    }

    public static void main(String[] args) {
        applicationContext = 
          new AnnotationConfigApplicationContext(SpringComponentScanApp.class);

        for (String beanName : applicationContext.getBeanDefinitionNames()) {
            System.out.println(beanName);
        }
    }
}

또한 com.baeldung.componentscan.springapp.animals 패키지 CatDog 구성 요소  가 있다고 가정 해 보겠습니다  .

package com.baeldung.componentscan.springapp.animals;
// ...
@Component
public class Cat {}
package com.baeldung.componentscan.springapp.animals;
// ...
@Component
public class Dog {}

마지막으로 com.baeldung.componentscan.springapp.flowers 패키지에 Rose 구성 요소  가 있습니다  .

package com.baeldung.componentscan.springapp.flowers;
// ...
@Component
public class Rose {}

main () 메서드 의 출력  에는 com.baeldung.componentscan.springapp 패키지 및 하위 패키지 의 모든 빈이 포함  됩니다.

springComponentScanApp
cat
dog
rose
exampleBean

이 어노테이션됩니다으로 기본 응용 프로그램 클래스는 빈 것을 참고 @Configuration,  A는 @Component .

또한 기본 응용 프로그램 클래스와 구성 클래스가 반드시 동일하지는 않습니다. 서로 다르면 메인 애플리케이션 클래스를 어디에 둘지는 중요하지 않습니다. 구성 클래스의 위치 만 중요하며 구성 요소 검색은 기본적으로 패키지에서 시작됩니다 .

마지막으로, 예제에서 @ComponentScan 은 다음과 같습니다.

@ComponentScan(basePackages = "com.baeldung.componentscan.springapp")

여기서 basePackages  인수는 스캔 할 패키지 또는 패키지 배열입니다.

2.2. Spring Boot 애플리케이션에서 @ComponentScan 사용

Spring Boot의 트릭은 많은 일이 암시 적으로 발생한다는 것입니다. @SpringBootApplication 어노테이션을 사용  하지만 다음과 같은 세 가지 어노테이션의 조합 일뿐입니다.

@Configuration
@EnableAutoConfiguration
@ComponentScan

com.baeldung.componentscan.springbootapp 패키지에 유사한 구조를 만들어 보겠습니다  . 이번에 주요 응용 프로그램은 다음과 같습니다.

package com.baeldung.componentscan.springbootapp;
// ...
@SpringBootApplication
public class SpringBootComponentScanApp {
    private static ApplicationContext applicationContext;

    @Bean
    public ExampleBean exampleBean() {
        return new ExampleBean();
    }

    public static void main(String[] args) {
        applicationContext = SpringApplication.run(SpringBootComponentScanApp.class, args);
        checkBeansPresence(
          "cat", "dog", "rose", "exampleBean", "springBootComponentScanApp");

    }

    private static void checkBeansPresence(String... beans) {
        for (String beanName : beans) {
            System.out.println("Is " + beanName + " in ApplicationContext: " + 
              applicationContext.containsBean(beanName));
        }
    }
}

다른 모든 패키지와 클래스는 동일하게 유지되며 가까운 com.baeldung.componentscan.springbootapp 패키지에 복사합니다  .

Spring Boot는 이전 예제와 유사하게 패키지를 스캔합니다. 출력을 확인해 보겠습니다.

Is cat in ApplicationContext: true
Is dog in ApplicationContext: true
Is rose in ApplicationContext: true
Is exampleBean in ApplicationContext: true
Is springBootComponentScanApp in ApplicationContext: true

두 번째 예제에서 빈이 존재하는지 확인하는 이유는 (모든 빈을 인쇄하는 것과는 반대로) 출력이 너무 클 수 있기 때문입니다.

이는 Spring Boot가 pom.xml 파일 의 의존성에 의존하여 많은 빈을 자동으로 생성 하도록하는 암시 적 @EnableAutoConfiguration 어노테이션 때문입니다 .

3. 인수가있는 @ComponentScan

이제 스캔 경로를 사용자 지정해 보겠습니다. 예를 들어 Rose bean 을 제외하고 싶다고 가정 해 보겠습니다  .

3.1. 특정 패키지 용 @ComponentScan

몇 가지 방법으로 할 수 있습니다. 먼저 기본 패키지를 변경할 수 있습니다.

@ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals")
@Configuration
public class SpringComponentScanApp {
   // ...
}

이제 출력은 다음과 같습니다.

springComponentScanApp
cat
dog
exampleBean

이것 뒤에 무엇이 있는지 보자 :

  • SpringComponentScanAppAnnotationConfigApplicationContext에 인수로 전달 된 구성이므로 생성됩니다.
  • exampleBean 은 구성 내부에 구성된 빈입니다.
  • catdog 는 지정된 com.baeldung.componentscan.springapp.animals 패키지에 있습니다.

위에 나열된 모든 사용자 지정은 Spring Boot에서도 적용 할 수 있습니다. @ComponentScan  을 @SpringBootApplication함께 사용할 수 있으며 결과는 동일합니다.

@SpringBootApplication
@ComponentScan(basePackages = "com.baeldung.componentscan.springbootapp.animals")

3.2. 제외가있는 @ComponentScan

또 다른 방법은 필터를 사용하여 제외 할 클래스의 패턴을 지정하는 것입니다.

@ComponentScan(excludeFilters = 
  @ComponentScan.Filter(type=FilterType.REGEX,
    pattern="com\\.baeldung\\.componentscan\\.springapp\\.flowers\\..*"))

어노테이션은 스캔 된 클래스 를 필터링 하기 위한 몇 가지 유연한 옵션을 지원하므로 다른 필터 유형을 선택할 수도 있습니다 .

@ComponentScan(excludeFilters = 
  @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Rose.class))

4. 기본 패키지

@Configuration 클래스 를 기본 패키지에 넣는 것을 피해야  합니다 (즉, 패키지를 전혀 지정하지 않음). 이 경우 Spring은 클래스 경로의 모든 jar에있는 모든 클래스를 스캔합니다. 이로 인해 오류가 발생하고 응용 프로그램이 시작되지 않을 수 있습니다.

5. 결론

이 기사에서는 기본적으로 Spring이 스캔하는 패키지와 이러한 경로를 사용자 정의하는 방법을 배웠습니다.

평소처럼 전체 코드는 GitHub에서 사용할 수  있습니다 .