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 패키지 에 Cat 및 Dog 구성 요소 가 있다고 가정 해 보겠습니다 .
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
이것 뒤에 무엇이 있는지 보자 :
- SpringComponentScanApp 은 AnnotationConfigApplicationContext에 인수로 전달 된 구성이므로 생성됩니다.
- exampleBean 은 구성 내부에 구성된 빈입니다.
- cat 및 dog 는 지정된 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이 스캔하는 패키지와 이러한 경로를 사용자 정의하는 방법을 배웠습니다.