Spring Boot Package Scanning Configuration

scanBasePackages Spring Boot This tutorial will guide you on the different ways to configure component scanning within Spring Boot. It will provide examples on how to correctly configure component scanning, and explain the more sophisticated features available such as exclusion filters and patterns.

@SpringBootApplication and scanBasePackages

If you are working with Spring Boot, your application likely already includes the @SpringBootApplication annotation as it is needed for bootstrapping your project.

As a result, you can combine any of the available parameters:

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(
    scanBasePackages = { "com.codetinkering.*" }, 
    scanBasePackageClasses = { BaseConfig.class },
    excludeName = { "com.codetinkering.IgnoreMe" },
    exclude = { IgnoreMe.class }
)
public class ExampleApplication {
...

Notice how scanBasePackages allows you to provide a wildcard to your package parameter so that any sub-packages will also be scanned? ScanBassePackageClasses works similarly but provides an array of classes to be provided instead of strings. All four of the following parameters can be used in the @SpringBootApplication annotation.

  • scanBasePackages - Takes in a string array and allows wildcard string filtering for package names, thereby allowing entire package directories to be included or scanned.
  • scanbasePackageClasses - Allows specific inclusion of classes provided via an array.
  • excludeName - Allows exclusion of classes by name (string), working similarly to the scanBasePackages parameter.
  • exclude - Provided an array of classes, these classes will be excluded from Spring package scanning, superseding any inclusion which may inadvertently happen from the scanBasePackages and scanBasePackageClasses parameters.

Other notes about @SpringBootApplication

@SpringBootApplication is a helper annotation and in effect, combines three different base annotations that you may already be familiar with in the Spring ecosystem:

  • @Configuration - informs the package scanner that the provided class has configuration elements, bean definitions, etc. and it should be included as part of the scan phase.
  • @EnableAutoConfiguration - Turns on the auto configuration of the Spring Application Context which will attempt to automatically auto-configure many aspects of your application, such as beans, configurations, scan property and yaml files, etc.
  • @ComponentScan - Identifies packages and classes which are to be scanned for configuration items such as beans, controllers, and more.

@ComponentScan Annotation Example

You can use wildcards to selectively include package names starting or ending with a certain string:

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@ComponentScan("com.*.example")
@Configuration
public class ExampleConfiguration { ... }

How to Exclude Classes with Wildcards and Regex in @ComponentScan

How about if you want to exclude certain packages while simultaneously include others? You can achieve this by including one or more excludeFilters. Use the FilterType.ASPECTJ type to enable wildcards or FilterType.REGEX if you would like to use regular expression formatted strings instead. It should be noted that you need to use the @ComponentScan annotation for this as this exclusion is not possible from the @SpringBootApplication.

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

@ComponentScan(
    excludeFilters = @ComponentScan.Filter(
        type = FilterType.ASPECTJ, 
        pattern = "com.codetinkering.ignore.*"))
@Configuration
public class ExampleConfiguration { ... }

Further parameters for @ComponentScan are included below:

  • ‌basePackages - The base packages takes in an array of strings and will then search these package structures and all the sub-packages to find any candidate classes which are marked with annotations such as @Configuration, @Controller, @Component, @Repository, etc. Any strings passed in may be formatted with a wildcard-type pattern (asterisk). This is the most commonly used parameter for the @ComponentScan annotation.\

    // @ComponentScan basePackages example
    @ComponentScan(
      basePackages = {"com.example.config", "com.example.misc"}
    )
    
  • basePackageClasses - The base package classes parameter utilizes an array of one or more classes that are to be scanned for candidates. This is useful should you want to include one or more additional classes without requiring a full package to be scanned. It can be combined with basePackages.

    // @ComponentScan basePackageClasses example
    @ComponentScan(
      basePackageClasses = {Example.class, Configuration.class}
    )
    
  • includeFilters - Allows you to utilize the Component Scan Filter to identify classes or packages which should be included in your package scanning. This is useful if you need something besides wildcard filtering, such as regex filtering, or even allows you to create a custom TypeFilter implementation which gives you full control of the scanning.

    // @ComponentScan includeFilters example
    @ComponentScan(
      includeFilters = @ComponentScan.Filter(
       type = FilterType.ASPECTJ, 
       pattern = "com.codetinkering.include.*")
    )
    
  • excludeFilters - Almost identical to the includeFilters parameter except it can be used for excluding certain classes or packages from scanning and discovery. This will likely be needed for large enterprises that have libraries containing a large mix of spring bean type classes that are annotated and you need to deliberately prevent them from being instantiated.

    // @ComponentScan excludeFilters example
    @ComponentScan(
      excludeFilters = @ComponentScan.Filter(
       type = FilterType.ASPECTJ, 
       pattern = "com.codetinkering.include.*")
    )
    
  • lazyInit - This lazyInit parameter allows for scanned beans to be declared in a lazy initialization pattern. This defaults to false and you should require a specific use case in mind before you set lazyInit as true as it may cause complex beans to be instantiated upon application runtime, potentially causing performance issues in your application.

// @ComponentScan lazyInit example
@ComponentScan(lazyInit = true)