Why do we need META-INF/spring.factories when create starters for Spring Boot applications? What if omit it at all or leave empty?

Doesn't the target application's @SpringBootApplication which is

a combination of three annotations @Configuration (used for Java-based configuration), @ComponentScan (used for component scanning), and @EnableAutoConfiguration

scan everything and find all beans from all the starters with no help of META-INF/spring.factories?

2

There are 2 best solutions below

0
On BEST ANSWER

Component Scanning would scan the packages that you give it. You could technically tell it to scan all the packages of your dependencies, too, and it would start loading up any beans defined in them. If you don’t specify any packages to scan, then Spring will use the base package where the annotation is applied, which would very likely not include beans defined in any dependency libs.

There’s another layer to this- a lot of the libraries you use may be using annotations like “@AutoConfigureBefore” to give spring instructions on the order of bean creation. Component Scanning will not respect that, which could result in some weird behaviors if some dependency tries to override a bean from another which is annotated with @ConditionalOnMissingBean (I.e. create this bean only if it doesn’t exist.) You could easily end up with name collision issues where that bean actually gets created first, and then the override bean is created, too.

So the answer seems to be no. You need spring.factories.

0
On

Doesn't the target application's @SpringBootApplication scan everything...

No, it doesn't scan everything because if it was it could take a lot of time and resources. Think about it in a way that in order to understand whether the file with an extension *.class contains a bean (something annotated with @Component for example) it needs at least to read a class and analyze the byte code or even load it into memory to check the annotation by reflection.

So if your application's root package is in com.sample.app (the package with the class annotated with @SpringBootApplication), then spring boot by convention scans only the beans in this package and the packages beneath it. This means that it won't scan any thirdparties (assuming they won't be placed in com.sample.app anyway).

Now Its true that you can change the rules of component scanning, but again, you don't want to scan everything for performance reasons at least.

So Autoconfiguration modules (technically implemented with META-INF/spring.factories can specify an additional place (classes annotated with @Configuration) that spring boot will load despite the fact that they are not placed under the packages of your application or, in other words, they do not obey the default component scanning rules.

In addition, spring.factories file allows to specify much more than auto configuration rules, you can specify environment post processors there for example, and other stuff that can be useful for your application, probably mostly beneficial at the level of application infrastructure, but still.