exclude @Component from @ComponentScan

后端 未结 7 1430
暖寄归人
暖寄归人 2020-11-28 04:10

I have a component that I want to exclude from a @ComponentScan in a particular @Configuration:

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


        
相关标签:
7条回答
  • Another approach is to use new conditional annotations. Since plain Spring 4 you can use @Conditional annotation:

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

    and define conditional logic for registering Foo component:

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

    Conditional logic can be based on context, because you have access to bean factory. For Example when "Bar" component is not registered as 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.

    0 讨论(0)
  • 2020-11-28 04:22

    Using explicit types in scan filters is ugly for me. I believe more elegant approach is to create own marker annotation:

    @Retention(RetentionPolicy.RUNTIME)
    public @interface IgnoreDuringScan {
    }
    

    Mark component that should be excluded with it:

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

    And exclude this annotation from your component scan:

    @ComponentScan(excludeFilters = @Filter(IgnoreDuringScan.class))
    public class MySpringConfiguration {}
    
    0 讨论(0)
  • 2020-11-28 04:25

    The configuration seem alright, except that you should use excludeFilters instead of excludes:

    @Configuration @EnableSpringConfigured
    @ComponentScan(basePackages = {"com.example"}, excludeFilters={
      @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value=Foo.class)})
    public class MySpringConfiguration {}
    
    0 讨论(0)
  • 2020-11-28 04:25

    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) })
    
    0 讨论(0)
  • 2020-11-28 04:27

    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 {}
    
    0 讨论(0)
  • In case of excluding test component or test configuration, Spring Boot 1.4 introduced new testing annotations @TestComponent and @TestConfiguration.

    0 讨论(0)
提交回复
热议问题