Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:

>> GET ACCESS NOW

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

NPI – Lightrun – Spring (partner)

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

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. Furthermore, 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.

Further reading:

Spring Bean Annotations

Learn how and when to use the standard Spring bean annotations - @Component, @Repository, @Service and @Controller.

Spring @ComponentScan – Filter Types

Explore different types of filter options available with the @ComponentScan annotation.

Create a Custom Auto-Configuration with Spring Boot

A quick, practical guide to creating a custom auto-configuration in Spring Boot.

2. @ComponentScan Without Arguments

2.1. Using @ComponentScan in a Spring Application

With Spring, we use the @ComponentScan annotation along with the @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);
        }
    }
}

In addition, 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 {}

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 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.

We should 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 we 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")

The 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 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.

3.1. @ComponentScan for Specific Packages

We can do this a few different 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

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")

3.2. @ComponentScan with Multiple Packages

Spring provides a convenient way to specify multiple package names. To do so, we need to use a string array.

Each string of the array denotes a package name:

@ComponentScan(basePackages = {"com.baeldung.componentscan.springapp.animals", "com.baeldung.componentscan.springapp.flowers"})

Alternatively, since spring 4.1.1, we can use a comma, a semicolon, or a space to separate the packages list:

@ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals;com.baeldung.componentscan.springapp.flowers")
@ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals,com.baeldung.componentscan.springapp.flowers")
@ComponentScan(basePackages = "com.baeldung.componentscan.springapp.animals com.baeldung.componentscan.springapp.flowers")

3.3. @ComponentScan with Exclusions

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\\..*"))

We can also choose a different filter type, as the annotation supports several flexible options for filtering the scanned classes:

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

4. The Default Package

We should avoid putting the @Configuration class in the default package (i.e. by not specifying the package at all). If we do, Spring scans all the classes in all jars in a classpath, which causes errors and the application probably doesn't start.

5. Conclusion

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

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

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:

>> GET ACCESS NOW

Generic footer banner
2 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Comments are closed on this article!