@ComponentScan 주석을 사용하여 여러 경로를 스캔하는 방법은 무엇입니까?


89

저는 Spring 3.1을 사용하고 @Configuration있으며 및 @ComponentScan속성을 사용하여 애플리케이션을 부트 스트랩하고 있습니다.

실제 시작은

new AnnotationConfigApplicationContext(MyRootConfigurationClass.class);

이 구성 클래스는

@Configuration
@ComponentScan("com.my.package")
public class MyRootConfigurationClass

그리고 이것은 잘 작동합니다. 그러나 내가 스캔 한 패키지에 대해 좀 더 구체적으로 알고 싶습니다.

@Configuration
@ComponentScan("com.my.package.first,com.my.package.second")
public class MyRootConfigurationClass

그러나 이것은 @Component주석을 사용하여 지정된 구성 요소를 찾을 수 없다는 오류와 함께 실패합니다 .

내가 추구하는 일을하는 올바른 방법은 무엇입니까?

감사


내가 말할 수있는 한 거의 동시에 두 개의 정답이 주어졌습니다. 그가 점수가 적다는 이유만으로 헤지에 동의하지만 둘 다 감사합니다.
프로그래밍 가이

kotlin 버전에 대해 똑같은 일이 궁금하다면 this one stackoverflow.com/a/62818187/7747942
Sylhare

답변:


159

@ComponentScan 은 다음과 같이 문자열 배열을 사용합니다.

@ComponentScan({"com.my.package.first","com.my.package.second"})

하나의 문자열로 여러 패키지 이름을 제공하면 Spring은 이것을 하나의 패키지 이름으로 해석하므로 찾을 수 없습니다.


48

기본 패키지 위치를 문자열로 지정하는 또 다른 유형 안전 대안 이 있습니다. 여기에서 API를 참조하십시오 . 그러나 아래에 또한 설명되어 있습니다.

@ComponentScan(basePackageClasses = {ExampleController.class, ExampleModel.class, ExmapleView.class})

basePackageClasses 사용클래스 참조와 함께 지정자를 Spring에 해당 패키지를 스캔하도록 지시 하지만 ( 언급 된 대안 처럼 )이 방법은 모두 형식에 안전 하며 향후 리팩토링을위한 IDE 지원 을 추가합니다 .

API에서 읽은 Spring은이 속성에 대한 참조로 사용되는 것 외에 다른 목적이없는 스캔하려는 각 패키지에 no-op 마커 클래스 또는 인터페이스를 생성 할 것을 제안합니다.

IMO, 나는 마커 클래스를 좋아하지 않지만 (다시 말하지만, 패키지 정보 클래스와 거의 비슷합니다) 유형 안전성, IDE 지원 및이 스캔에 포함해야하는 기본 패키지 수를 대폭 줄였습니다. 의심 할 여지없이 훨씬 더 나은 옵션입니다.


누군가 @ComponentScan ({ "com.app", "com.controllers"})이 나를 위해 작동하지 않지만 @ComponentScan (basePackageClasses = { "com.controllers"})가 잘 작동하는 이유를 설명 할 수 있습니까? 나는 모든 클래스 이름을 쓰는 지루한 찾을
xaverras

3
스캔하려는 패키지에 대해 패키지에서 하나의 클래스 만 지정하면됩니다. 이것을 마커 클래스라고합니다. 클래스가없는 계층 구조에서 더 높은 패키지를 스캔해야하는 경우 spring은 패키지 스캔 목적으로 만 해당 패키지에 정의 된 "스프링 마커"인터페이스 또는 최종 클래스를 사용하는 기술을 제안합니다.
Prancer

17

패키지 이름을 별도로 제공하십시오. 패키지 이름에는이 필요 String[]합니다.

대신 :

@ComponentScan("com.my.package.first,com.my.package.second")

이것을 사용하십시오 :

@ComponentScan({"com.my.package.first","com.my.package.second"})

10

이를 수행하는 또 다른 방법은 basePackages필드를 사용하는 것 입니다. ComponentScan 주석 내부의 필드입니다.

@ComponentScan(basePackages={"com.firstpackage","com.secondpackage"})

jar 파일에서 ComponentScan 주석 .class를 살펴보면 문자열 배열을받는 basePackages 필드를 볼 수 있습니다.

public @interface ComponentScan {
String[] basePackages() default {};
}

또는 클래스를 명시 적으로 언급 할 수 있습니다. 클래스 배열을받습니다.

Class<?>[]  basePackageClasses

4

ComponentScan을 사용하여 다음을 사용하여 여러 패키지를 스캔합니다.

@ComponentScan({"com.my.package.first","com.my.package.second"})


1

이 종속성을 pom.xml에 추가했는지 확인하십시오.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

반 시간 가까이를 지출 한 후 덕분에이 누락 된 의존성이었다
DvixExtract

1

나는 사용한다:

@ComponentScan(basePackages = {"com.package1","com.package2","com.package3", "com.packagen"})

0

@ComponentScans 주석을 사용할 수도 있습니다.

@ComponentScans(value = { @ComponentScan("com.my.package.first"),
                          @ComponentScan("com.my.package.second") })

4
귀하의 답변에 설명을 추가하는 것을 고려하십시오
yeya
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.