I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll cover component scanning in Spring. When working with Spring, we can annotate our classes in order to make them into Spring beans. But, besides that, we can tell Spring where to search for these annotated classes as not all of them must become beans in this particular run.

Of course, there are some defaults for component scanning but we can also customize the packages for search.

First, let’s look at the default settings.

2. @ComponentScan Without Arguments

2.1. Using @ComponentScan in a Spring Application

With Spring, we use the @ComponentScan annotation along with @Configuration annotation to specify the packages that we want to be scanned. @ComponentScan without arguments tells Spring to scan the current package and all of its sub-packages.

Let’s say we have the following @Configuration in com.baeldung.componentscan.springapp package:

@Configuration
@ComponentScan
public class SpringComponentScanApp {
    private static ApplicationContext applicationContext;

    @Bean
    public ExampleBean exampleBean() {
        return new ExampleBean();
    }

    public static void main(String[] args) {
        applicationContext = new AnnotationConfigApplicationContext(SpringComponentScanApp.class);

        for (String beanName : applicationContext.getBeanDefinitionNames()) {
            System.out.println(beanName);
        }
    }
}

Also, let’s say we have the Cat and Dog components in com.baeldung.componentscan.springapp.animals package:

package com.baeldung.componentscan.springapp.animals;
// ...
@Component
public class Cat {}
package com.baeldung.componentscan.springapp.animals;
// ...
@Component
public class Dog {}

And finally, we have the Rose component in com.baeldung.componentscan.springapp.flowers package:

package com.baeldung.componentscan.springapp.flowers;
// ...
@Component
public class Rose {}

The output of the main() method will contain all the beans of com.baeldung.componentscan.springapp package and of its sub-packages:

springComponentScanApp
cat
dog
rose
exampleBean

Note that the main application class is also a bean as it’s annotated with @Configuration, which is a @Component.

Also, note that the main application class and the configuration class are not necessarily the same. If they are different, it doesn’t matter where to put the main application class. Only the location of the configuration class matters as component scanning starts from its package by default.

Finally, note that in our example @ComponentScan is equivalent to:

@ComponentScan(basePackages = "com.baeldung.componentscan.springapp")

where basePackages argument is a package or an array of packages for scanning.

2.2. Using @ComponentScan in a Spring Boot Application

The trick with Spring Boot is that many things happen implicitly. We use the @SpringBootApplication annotation, but it’s just a combination of three annotations:

@Configuration
@EnableAutoConfiguration
@ComponentScan

Let’s create a similar structure in com.baeldung.componentscan.springbootapp package. This time the main application will be:

package com.baeldung.componentscan.springbootapp;
// ...
@SpringBootApplication
public class SpringBootComponentScanApp {
    private static ApplicationContext applicationContext;

    @Bean
    public ExampleBean exampleBean() {
        return new ExampleBean();
    }

    public static void main(String[] args) {
        applicationContext = SpringApplication.run(SpringBootComponentScanApp.class, args);
        checkBeansPresence("cat", "dog", "rose", "exampleBean", "springBootComponentScanApp");

    }

    private static void checkBeansPresence(String... beans) {
        for (String beanName : beans) {
            System.out.println("Is " + beanName + " in ApplicationContext: " + 
              applicationContext.containsBean(beanName));
        }
    }
}

All other packages and classes remain the same, we’ll just copy them to the nearby com.baeldung.componentscan.springbootapp package.

Spring Boot scans packages similarly to our previous example. Let’s check the output:

Is cat in ApplicationContext: true
Is dog in ApplicationContext: true
Is rose in ApplicationContext: true
Is exampleBean in ApplicationContext: true
Is springBootComponentScanApp in ApplicationContext: true

The reason we’re just checking the beans for existence in our second example (as opposed to printing out all the beans), is that the output would be too large.

This is because of the implicit @EnableAutoConfiguration annotation which makes Spring Boot create many beans automatically, relying on the dependencies in pom.xml file.

3. @ComponentScan With Arguments

Now let’s customize the paths for scanning. For example, let’s say we want to exclude the Rose bean.

We can do it in a few ways. First, we can change the base package:

@ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals")
@Configuration
public class SpringComponentScanApp {
   // ...
}

Now the output will be:

springComponentScanApp
cat
dog
exampleBean

Let’s see what’s behind this:

  • springComponentScanApp is created as it’s a configuration passed as an argument to the AnnotationConfigApplicationContext
  • exampleBean is a bean configured inside the configuration
  • cat and dog are in the specified com.baeldung.componentscan.springapp.animals package

Another way is to use a filter, specifying the pattern for the classes to exclude:

@ComponentScan(excludeFilters = 
  @ComponentScan.Filter(type=FilterType.REGEX,
    pattern="com\\.baeldung\\.componentscan\\.springapp\\.flowers\\..*"))

Also, we can use a different filter type:

@ComponentScan(excludeFilters = 
  @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Rose.class))

All of the above-listed customizations are applicable in Spring Boot too. We can use @ComponentScan together with @SpringBootApplication and the result will be the same:

@SpringBootApplication
@ComponentScan(basePackages = "com.baeldung.componentscan.springbootapp.animals")

4. The Default Package

We should avoid putting the @Configuration class in the default package (i.e. by not specifying the package at all). In this case, Spring scans all the classes in all jars in a classpath. That causes errors and the application probably doesn’t start.

5. Conclusion

In this article, we’ve learned which packages Spring scans by default and how to customize these paths.

As usual, the complete code is available over on GitHub.

I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE LESSONS

newest oldest most voted
Notify of
小郭
Guest
小郭

Also, note that the main application class and the configuration class are not necessarily the same. If they are different, it doesn’t matter where to put the main application class. Only the location of the configuration class matters as component scanning starts from its package by default. it means main application class can only using @Configuration and configuration class can using @ComponentScan annotation, and component scan decide the configuration class? But i found only @ComponentScan using in main application class , it can work , so your thought is right? please check it again. if it is possible , please… Read more »

Loredana Crusoveanu
Editor

Hello,

You can have a @Configuration class by itself, and load it into the context using the AnnotationConfigApplicationContext in the main() method as shown in the example.

If you have a Spring Boot application, then the @SpringBootApplication annotation includes both @Configuration and @ComponentScan. Here’s a guide to getting started with a Spring Boot application: https://www.baeldung.com/spring-boot-start