복붙노트

[SPRING] @ComponentScan에서 @Component 제외

SPRING

@ComponentScan에서 @Component 제외

특정 @Configuration의 @ComponentScan에서 제외시키려는 구성 요소가 있습니다.

@Component("foo") class Foo {
...
}

그렇지 않으면 내 프로젝트에서 다른 클래스와 충돌하는 것 같습니다. 필자는 충돌을 완전히 이해하지 못하지만, @Component 주석을 주석 처리하면 원하는대로 작동합니다. 그러나이 라이브러리에 의존하는 다른 프로젝트는이 클래스가 Spring에 의해 관리되기를 기대하기 때문에 프로젝트에서 건너 뛰고 싶습니다.

@ ComponentScan.Filter를 사용해 보았습니다.

@Configuration 
@EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
  @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}

그러나 그것은 작동하는 것처럼 보이지 않습니다. FilterType.ASSIGNABLE_TYPE을 사용하려고하면 겉보기에 임의의 클래스를로드 할 수 없다는 이상한 오류가 발생합니다.

나는 또한 다음과 같이 type = FilterType.CUSTOM을 사용하여 시도했다.

class ExcludeFooFilter implements TypeFilter {
    @Override
    public boolean match(MetadataReader metadataReader,
            MetadataReaderFactory metadataReaderFactory) throws IOException {
        return metadataReader.getClass() == Foo.class;
    }
}

@Configuration @EnableSpringConfigured
@ComponentScan(basePackages = {"com.example"}, excludeFilters={
  @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
public class MySpringConfiguration {}

하지만 원하는대로 구성 요소를 검사에서 제외하지 않는 것 같습니다.

제외하려면 어떻게해야합니까?

해결법

  1. ==============================

    1.구성은 exclude 대신 excludeFilters를 사용해야한다는 점을 제외하고는 괜찮습니다.

    구성은 exclude 대신 excludeFilters를 사용해야한다는 점을 제외하고는 괜찮습니다.

    @Configuration @EnableSpringConfigured
    @ComponentScan(basePackages = {"com.example"}, excludeFilters={
      @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
    public class MySpringConfiguration {}
    
  2. ==============================

    2.스캔 필터에서 명시적인 유형을 사용하는 것은 저에게는보기 흉한 행위입니다. 더 우아한 접근 방식은 자신의 마커 주석을 만드는 것이라고 생각합니다.

    스캔 필터에서 명시적인 유형을 사용하는 것은 저에게는보기 흉한 행위입니다. 더 우아한 접근 방식은 자신의 마커 주석을 만드는 것이라고 생각합니다.

    public @interface IgnoreDuringScan {
    }
    

    구성 요소와 함께 제외해야하는 구성 요소를 표시하십시오.

    @Component("foo") 
    @IgnoreDuringScan
    class Foo {
        ...
    }
    

    그리고이 주석을 구성 요소 검사에서 제외하십시오.

    @ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class))
    public class MySpringConfiguration {}
    
  3. ==============================

    3.또 다른 접근법은 새로운 조건부 주석을 사용하는 것입니다. 일반 Spring 4부터는 @Conditional annotation을 사용할 수 있습니다 :

    또 다른 접근법은 새로운 조건부 주석을 사용하는 것입니다. 일반 Spring 4부터는 @Conditional annotation을 사용할 수 있습니다 :

    @Component("foo")
    @Conditional(FooCondition.class)
    class Foo {
        ...
    }
    

    Foo 구성 요소를 등록하기위한 조건부 논리를 정의합니다.

    public class FooCondition implements Condition{
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            // return [your conditional logic]
        }     
    }
    

    Bean 팩토리에 액세스 할 수 있으므로 조건부 논리는 컨텍스트를 기반으로 할 수 있습니다. 예를 들어, "Bar"컴포넌트가 bean으로 등록되지 않은 경우 :

        return !context.getBeanFactory().containsBean(Bar.class.getSimpleName());
    

    Spring Boot (모든 새로운 Spring 프로젝트에 사용해야 함)를 사용하면 다음 조건부 주석을 사용할 수 있습니다.

    이런 식으로 조건 클래스를 만들지 않아도됩니다. 더 자세한 정보는 Spring Boot 문서를 참조하십시오.

  4. ==============================

    4.둘 이상의 excludeFilters 기준을 정의해야하는 경우 배열을 사용해야합니다.

    둘 이상의 excludeFilters 기준을 정의해야하는 경우 배열을 사용해야합니다.

    이 코드 섹션의 인스턴스의 경우 org.xxx.yyy 패키지의 모든 클래스와 다른 특정 클래스 인 MyClassToExclude를 제외하려고합니다.

     @ComponentScan(            
            excludeFilters = {
                    @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.xxx.yyy.*"),
                    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MyClassToExclude.class) })
    
  5. ==============================

    5.@Configuration, @EnableAutoConfiguration 및 @ComponentScan을 사용할 때 특정 구성 클래스를 제외하려고 할 때 문제가 발생했습니다. 문제는 작동하지 않습니다!

    @Configuration, @EnableAutoConfiguration 및 @ComponentScan을 사용할 때 특정 구성 클래스를 제외하려고 할 때 문제가 발생했습니다. 문제는 작동하지 않습니다!

    결국 스프링 문서에 따라 하나의 주석에서 위의 세 가지 기능과 동일한 기능을 수행하는 @SpringBootApplication을 사용하여 문제를 해결했습니다.

    또 다른 팁은 패키지 스캔을 수정하지 않고 먼저 시도하는 것입니다 (basePackages 필터 제외).

    @SpringBootApplication(exclude= {Foo.class})
    public class MySpringConfiguration {}
    
  6. ==============================

    6.테스트 구성 요소 또는 테스트 구성을 제외하는 경우, Spring Boot 1.4는 @TestComponent 및 @TestConfiguration이라는 새로운 테스트 주석을 도입했습니다.

    테스트 구성 요소 또는 테스트 구성을 제외하는 경우, Spring Boot 1.4는 @TestComponent 및 @TestConfiguration이라는 새로운 테스트 주석을 도입했습니다.

  7. ==============================

    7.앱 컨텍스트에서 감사 @Aspect @Component를 제외해야했지만 몇 가지 테스트 클래스에만 필요했습니다. 애스펙트 클래스에서 @Profile ( "audit")을 사용했다. 정상 작동을위한 프로파일을 포함하지만 특정 테스트 클래스에이 프로파일을 제외시킵니다 (@ActiveProfiles에 넣지 마십시오).

    앱 컨텍스트에서 감사 @Aspect @Component를 제외해야했지만 몇 가지 테스트 클래스에만 필요했습니다. 애스펙트 클래스에서 @Profile ( "audit")을 사용했다. 정상 작동을위한 프로파일을 포함하지만 특정 테스트 클래스에이 프로파일을 제외시킵니다 (@ActiveProfiles에 넣지 마십시오).

  8. from https://stackoverflow.com/questions/18992880/exclude-component-from-componentscan by cc-by-sa and MIT license