Annotation Interface ComponentScanExcludingConfigurationForTest


@Target(TYPE) @Retention(RUNTIME) @Configuration @ComponentScan(excludeFilters=) public @interface ComponentScanExcludingConfigurationForTest
A simple convenience replacement for @ComponentScan which excludes any configuration classes employing the special @ConfigurationForTest annotation instead of the standard @Configuration annotation. This is meant as a solution for a rather common problem that arises when your application uses @ComponentScan to find @Services, @Components etc, and have integration tests that reside in "src/test/java", but has the same package as the application code (to allow for package access). In the tests, you might want to include the entire application's Spring configuration, thus you include the same @ComponentScan. The problem now is that since all the test classes are included on the classpath when running a test, and at the same time reside in the same package structure, the component scan will pick up all tests' @Configuration classes too. This is absolutely not what you wanted - in particular if e.g. two different tests tries to set up two different variants of a mock collaborating Mats endpoint (that is, an application-external service that this application communicates with): You'll end up trying to take up both variants at the same time, and since they have the same endpointId, Mats will refuse this.

If you employ this annotation (@ComponentScanExcludingConfigurationForTest) - or set up the same "excludeFilters" as this annotation does - you will not include any configuration classes that are annotated with @ConfigurationForTest instead of the ordinary @Configuration. However, each test will still pick up its own inner static @ConfigurationForTest class(es).

A test class employing @ConfigurationForTest would look something like this:

 @MatsTestProfile // <- If you employ the JmsSpringConnectionFactoryProducer's logic to handle JMS ConnectionFactory
 @RunWith(SpringRunner.class)
 public class IntegrationTestClass {

     @ConfigurationForTest
     @Import(ApplicationSpringConfigurationClass_Using_ComponentScanExcludingConfigurationForTest.class)
     public static class InnerStaticConfigurationClassForTest {
         // @Bean definitions
         // @MatsMapping definitions
     }

     // @Inject'ed fields..
     // @Test-methods..
 }
 

If you want to do the exclusion on your own, you can use the standard @ComponentScan, making sure you include this excludeFilters property:

  @ComponentScan(excludeFilters = {
      @Filter(type = FilterType.ANNOTATION, value = ConfigurationForTest.class)
  })
 

This class has @AliasFor all properties that Spring 4.x has on @ComponentScan. If new properties arrive later which you want to use, you will have to do the exclusion on your own.

NOTICE: An alternative way to achieve the same effect is to annotate the integration test class with @ContextConfiguration, pointing to both the application's Spring setup, and also the configuration class residing within the test class - but where the test's configuration class is not annotated with @Configuration. Such an integration test class would look something like this:

 @MatsTestProfile // <- If you employ the JmsSpringConnectionFactoryProducer's logic to handle JMS ConnectionFactory
 @RunWith(SpringRunner.class)
 @ContextConfiguration(classes = { ApplicationSpringConfigurationClass_Using_ComponentScan.class,
         InnerStaticConfigurationClassForTest.class })
 public class IntegrationTestClass {

     // Notice how this configuration class is NOT annotated with @Configuration, to avoid being picked up by
     // application's @ComponentScan
     public static class InnerStaticConfigurationClassForTest {
         // @Bean definitions
         // @MatsMapping definitions
     }

     // @Inject'ed fields..
     // @Test-methods..
 }
 
See Also:
  • Optional Element Summary

    Optional Elements
    Modifier and Type
    Optional Element
    Description
    Class<?>[]
    Type-safe alternative to basePackages() for specifying the packages to scan for annotated components.
    Base packages to scan for annotated components.
    org.springframework.context.annotation.ComponentScan.Filter[]
    Specifies which types are not eligible for component scanning.
    org.springframework.context.annotation.ComponentScan.Filter[]
    Specifies which types are eligible for component scanning.
    boolean
    Specify whether scanned beans should be registered for lazy initialization.
    Class<? extends org.springframework.beans.factory.support.BeanNameGenerator>
    The BeanNameGenerator class to be used for naming detected components within the Spring container.
    Controls the class files eligible for component detection.
    org.springframework.context.annotation.ScopedProxyMode
    Indicates whether proxies should be generated for detected components, which may be necessary when using scopes in a proxy-style fashion.
    Class<? extends org.springframework.context.annotation.ScopeMetadataResolver>
    The ScopeMetadataResolver to be used for resolving the scope of detected components.
    boolean
    Indicates whether automatic detection of classes annotated with @Component @Repository, @Service, or @Controller should be enabled.
    Alias for basePackages().
  • Element Details

    • value

      @AliasFor(annotation=org.springframework.context.annotation.ComponentScan.class, attribute="value") String[] value
      Alias for basePackages().

      Allows for more concise annotation declarations if no other attributes are needed — for example, @ComponentScan("org.my.pkg") instead of @ComponentScan(basePackages = "org.my.pkg").

      Default:
      {}
    • basePackages

      @AliasFor(annotation=org.springframework.context.annotation.ComponentScan.class, attribute="basePackages") String[] basePackages
      Base packages to scan for annotated components.

      value() is an alias for (and mutually exclusive with) this attribute.

      Use basePackageClasses() for a type-safe alternative to String-based package names.

      Default:
      {}
    • basePackageClasses

      @AliasFor(annotation=org.springframework.context.annotation.ComponentScan.class, attribute="basePackageClasses") Class<?>[] basePackageClasses
      Type-safe alternative to basePackages() for specifying the packages to scan for annotated components. The package of each class specified will be scanned.

      Consider creating a special no-op marker class or interface in each package that serves no purpose other than being referenced by this attribute.

      Default:
      {}
    • nameGenerator

      @AliasFor(annotation=org.springframework.context.annotation.ComponentScan.class, attribute="nameGenerator") Class<? extends org.springframework.beans.factory.support.BeanNameGenerator> nameGenerator
      The BeanNameGenerator class to be used for naming detected components within the Spring container.

      The default value of the BeanNameGenerator interface itself indicates that the scanner used to process this @ComponentScan annotation should use its inherited bean name generator, e.g. the default AnnotationBeanNameGenerator or any custom instance supplied to the application context at bootstrap time.

      See Also:
      • AnnotationConfigApplicationContext.setBeanNameGenerator(BeanNameGenerator)
      Default:
      org.springframework.beans.factory.support.BeanNameGenerator.class
    • scopeResolver

      @AliasFor(annotation=org.springframework.context.annotation.ComponentScan.class, attribute="scopeResolver") Class<? extends org.springframework.context.annotation.ScopeMetadataResolver> scopeResolver
      The ScopeMetadataResolver to be used for resolving the scope of detected components.
      Default:
      org.springframework.context.annotation.AnnotationScopeMetadataResolver.class
    • scopedProxy

      @AliasFor(annotation=org.springframework.context.annotation.ComponentScan.class, attribute="scopedProxy") org.springframework.context.annotation.ScopedProxyMode scopedProxy
      Indicates whether proxies should be generated for detected components, which may be necessary when using scopes in a proxy-style fashion.

      The default is defer to the default behavior of the component scanner used to execute the actual scan.

      Note that setting this attribute overrides any value set for scopeResolver().

      See Also:
      • ClassPathBeanDefinitionScanner.setScopedProxyMode(ScopedProxyMode)
      Default:
      DEFAULT
    • resourcePattern

      @AliasFor(annotation=org.springframework.context.annotation.ComponentScan.class, attribute="resourcePattern") String resourcePattern
      Controls the class files eligible for component detection.

      Consider use of includeFilters() and excludeFilters() for a more flexible approach.

      Default:
      "**/*.class"
    • useDefaultFilters

      @AliasFor(annotation=org.springframework.context.annotation.ComponentScan.class, attribute="useDefaultFilters") boolean useDefaultFilters
      Indicates whether automatic detection of classes annotated with @Component @Repository, @Service, or @Controller should be enabled.
      Default:
      true
    • includeFilters

      @AliasFor(annotation=org.springframework.context.annotation.ComponentScan.class, attribute="includeFilters") org.springframework.context.annotation.ComponentScan.Filter[] includeFilters
      Specifies which types are eligible for component scanning.

      Further narrows the set of candidate components from everything in basePackages() to everything in the base packages that matches the given filter or filters.

      Note that these filters will be applied in addition to the default filters, if specified. Any type under the specified base packages which matches a given filter will be included, even if it does not match the default filters (i.e. is not annotated with @Component).

      See Also:
      Default:
      {}
    • excludeFilters

      @AliasFor(annotation=org.springframework.context.annotation.ComponentScan.class, attribute="excludeFilters") org.springframework.context.annotation.ComponentScan.Filter[] excludeFilters
      Specifies which types are not eligible for component scanning. NOTICE: For this special variant, the default is set to exclude @ConfigurationForTest annotated classes
      See Also:
      Default:
      {@org.springframework.context.annotation.ComponentScan.Filter(type=ANNOTATION, value={io.mats3.spring.ConfigurationForTest.class})}
    • lazyInit

      @AliasFor(annotation=org.springframework.context.annotation.ComponentScan.class, attribute="lazyInit") boolean lazyInit
      Specify whether scanned beans should be registered for lazy initialization.

      Default is false; switch this to true when desired.

      Since:
      4.1
      Default:
      false