programing tip

@ComponentScan에서 @Component 제외

itbloger 2020. 10. 21. 07:44
반응형

@ComponentScan에서 @Component 제외


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

@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임의의 클래스를로드 할 수 없다는 이상한 오류가 발생합니다.

원인 : java.io.FileNotFoundException : 클래스 경로 리소스 [junit / framework / TestCase.class]가 존재하지 않기 때문에 열 수 없습니다.

또한 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 {}

그러나 그것은 내가 원하는 것처럼 스캔에서 구성 요소를 제외하지 않는 것 같습니다.

어떻게 제외합니까?


excludeFilters대신 다음을 사용해야한다는 점을 제외하면 구성이 괜찮아 보입니다 excludes.

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

스캔 필터에서 명시 적 유형을 사용하는 것은 나에게 좋지 않습니다. 더 우아한 접근 방식은 자체 마커 주석을 만드는 것입니다.

public @interface IgnoreDuringScan {
}

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

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

구성 요소 스캔에서이 주석을 제외합니다.

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

또 다른 접근 방식은 새로운 조건부 주석을 사용하는 것입니다. 평범한 Spring 4 부터 @Conditional 주석을 사용할 수 있습니다.

@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]
    }     
}

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

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

With Spring Boot (should be used for EVERY new Spring project), you can use these conditional annotations:

  • @ConditionalOnBean
  • @ConditionalOnClass
  • @ConditionalOnExpression
  • @ConditionalOnJava
  • @ConditionalOnMissingBean
  • @ConditionalOnMissingClass
  • @ConditionalOnNotWebApplication
  • @ConditionalOnProperty
  • @ConditionalOnResource
  • @ConditionalOnWebApplication

You can avoid Condition class creation this way. Refer to Spring Boot docs for more detail.


In case you need to define two or more excludeFilters criteria, you have to use the array.

For instances in this section of code I want to exclude all the classes in the org.xxx.yyy package and another specific class, MyClassToExclude

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

I had an issue when using @Configuration, @EnableAutoConfiguration and @ComponentScan while trying to exclude specific configuration classes, the thing is it didn't work!

Eventually I solved the problem by using @SpringBootApplication, which according to Spring documentation does the same functionality as the three above in one annotation.

Another Tip is to try first without refining your package scan (without the basePackages filter).

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

In case of excluding test component or test configuration, Spring Boot 1.4 introduced new testing annotations @TestComponent and @TestConfiguration.


I needed to exclude an auditing @Aspect @Component from the app context but only for a few test classes. I ended up using @Profile("audit") on the aspect class; including the profile for normal operations but excluding it (don't put it in @ActiveProfiles) on the specific test classes.

참고URL : https://stackoverflow.com/questions/18992880/exclude-component-from-componentscan

반응형