43

I have problem with Spring Boot configuration.

I have created base Spring Boot project using https://start.spring.io/

And I have a problem, configuration works only for classes in sub catalog:

enter image description here

I have tried annotation @ComponentScan but it didn't help.

Do You have any idea what can I do with this?

0

6 Answers 6

76

The Spring Boot documentation for @SpringBootApplication states

Many Spring Boot developers always have their main class annotated with @Configuration, @EnableAutoConfiguration and @ComponentScan. Since these annotations are so frequently used together (especially if you follow the best practices above), Spring Boot provides a convenient @SpringBootApplication alternative.

The @SpringBootApplication annotation is equivalent to using @Configuration, @EnableAutoConfiguration and @ComponentScan with their default attributes: [...]

where the @ComponentScan javadoc states

If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.

That is, only the types that are in the same package as your ReadingListApplication will be scanned.

If you want a custom configuration, provide your own @Configuration, @EnableAutoConfiguration, and @ComponentScan, as appropriate.

3
  • 4
    What about if I have added another spring boot app as a mvn dependency, and then I want my parent app to scan this library? Commented Aug 30, 2018 at 14:26
  • “That is, only the types that are in the same package as your ReadingListApplication will be scanned." This is exactly what I am looking for, thank you. I do not only want to know what, but why.
    – GLPease
    Commented Aug 10, 2019 at 1:04
  • 2
    Just wanted to add that you may need to pay attention to how @SpringBootApplication configure each annotation as it matters. For example, the @ComponentScan is not just that but is actually @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) for SpringBoot 2.X.X. So be mindful, if you replacing @SpringBootApplication with your own individual configuration
    – tuan.dinh
    Commented Aug 5, 2020 at 3:00
30

Checking the Spring documentation:

http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/SpringBootApplication.html

You can override, with the @SpringBootApplication, the default values of component scan. You just need to include it as a parameters:

@SpringBootApplication(scanBasePackages = "entertainment")

or String array:

@SpringBootApplication(scanBasePackages = {"entertainment", "readinglist"})

22

When setting up a Spring boot project, have your Application class (the one that contains the @SpringBootApplication annotation in the base package.

One of the things the @SpringBootApplication does is a component scan. But, it only scans on sub-packages. i.e. if you put that class in com.mypackage, then it will scan for all classes in sub-packages i.e. com.mypackage.*.

If you do not want to do it this way, you can also add a @ComponentScan to a class specifying the root package i.e @ComponentScan("com.mypackage")

I would recommend you have a base package i.e com.mypackage. And within those packages, have your sub-packages. Have you class containing the @SpringBootApplication in that base package.

1
  • I'll do as You said parent package with config class and sub packages with my app code. Thank You.
    – Piotr Żak
    Commented Nov 10, 2015 at 9:32
7

I was having the same problem and to solve it I renamed my packages like this.

"com.project"

there you can place your SpringBootAplication main class, then just create the others packages beginning with "com.project"

"com.project.dao"

"com.project.controller"

Creating this sub project structure you have no need to use scanBasePackages in @SpringBootApplication annotation, doing this your main class will be able to find every component in your project.

And in case you chose to use scanBasePackages remember that you need to set all your components packages like this.

@SpringBootApplication(scanBasePackages = {"com.project.dao", "com.project.controller"})

1
  • There is no need to define all sub-packages individually, if they share a common base package. scanBasePackages = "com.project" should be sufficient (at least in 2024). Commented Apr 18 at 13:41
1

The Spring Boot team wanted to make you life easy and by default all the packages located under the package where the annotation @SpringBootApplication is found are scanned. In your example it means under the package of the class ReadingListApplication and the package readinglist (and below).

Following the example, as you did you can create a controller, a repository and a bean Book (based on the name we know it is from the domain).

Doing so there is some extra. You can define beans into the class ReadingListApplication, and these beans will be scanned. You can define Java configuration under the package readinglist and these beans will be scanned.

Nothing to be configured (only @SpringBootApplication to be used).

If you want to define a class outside the readinglist package then you need some configuration.

From the IDE or from the Java doc, look what is inside the annotation @SpringBootApplication and you will find scanBasePackages.

The parameter scanBasePackages does configure the packages to be scanned. If you want to add some extra packages like you did into your example, you have to use this annotation.

@SpringBootApplication(scanBasePackages = {"readinglist","entertainment"})

Of course, you have to add the package "readinglist" back because well, you configure the scanning explicitely and add all the extra packages you want, and in your example, only one, the package entertainment.

This way, both packages readinglist and entertainment (and of course below) will be scanned. You can for example, put some Java config into entertainment and these beans will be scanned.

0

For the scanning of packages to really work, you must do as follows.

@SpringBootApplication(scanBasePackages = {"com.your.package.test.*.*"})

The first asterisk tells you to scan all packages within the main path (com.your.package.test) and the second asterisk tells you to scan all files in each package.

For example:

com.your.package.test
|_ config
|_ business
|_ controller
|_ domain
|_ repository
1
  • 5
    wrong answer. you don't need to give asterisks. just specifying the base package is enough. it will recursively find the sub packages within the base package.
    – Mav55
    Commented May 6, 2021 at 14:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.