Why shall I not component-scan my auto-configuration?
Asked Answered
I

1

6

In Spring Boot's documentation it is clearly stated that auto-configurations must be specified via the spring.factories file:

Auto-configurations must be loaded that way only. Make sure that they are defined in a specific package space and that they are never the target of component scanning.

I did try to put a @Component on my auto-configuration class and made sure it will be picked up by component scanning. It seems to work.

While I do think it's bad practice, since it is very unlikely that component scanning will actually pick it up in a real world scenario, I am wondering why the documentation feel so strongly about it. Are there any other dangers that I fail to anticipate, and if so, which?

Edit: In https://youtu.be/jDchAEHIht0?t=734 Stéphane and Brian explain that there are two phases, one called "UserConfiguration Phase" and another "AutoConfiguration Phase". Following that thought would suggest, that using @ComponentScan on an auto-configuration class would move it to the "User Configuration Phase" which would basically break semantics of auto-configuration.

However, I've not been able to break it in my experiments. As long as I keep my @Conditional annotation it seems to work as expected...

Inez answered 3/9, 2020 at 18:6 Comment(1)
Because component=scanning happens later in the process and to when the spring.factories are read. Those are read quite early in the proces and thus could influence the component-scanning or available beans/postprocessors etc.Terricolous
N
9

It seems to work.

As you might suspect, there is a good reason for that note to be present in the documentation. The whole point of auto-configuration is that they are processed once the user configuration has been parsed for the simple reason that order is important.

If you have an application with configuration classes producing a bunch of beans, and you want to make sure a certain bean in an auto-configuration is not created if the user has expressed an opinion, you need to make damn sure that this auto-configuration is processed after the user configuration. The video that you've shared is describing that in more details, I would suggest to watch the complete section.

Are there any other dangers that I fail to anticipate, and if so, which?

Hopefully the explanation above and your own edit tell you. Auto-configurations are not user configurations. Declaring them in component scan is textbook of user configuration.

Nonconformist answered 13/9, 2020 at 8:47 Comment(5)
Does avoiding using configuration scan also includes not using it for detecting beans for auto configuration class itself? I get that autoconf class itself must not be picked up by component scan, but why wouldn't I use component scan annotation on configuration class(declared as autoconfigutation one in spring.factories) to pick up beans that should be autoconfigured? Ofc, making sure those components aren't target of any user component scan eitherImpatiens
An auto-configuration is rather an isolated thing that should be self describing. As such, I don't understand why you'd want to use component scanning there. Each @Bean method can have conditions and the auto-configuration should provide an overview of them.Nonconformist
I have some (potential)@Components that should be defined unconditionaly so @ComponentScan-ing them would make class source code a bit cleaner. But to avoid possible pitfalls I'll create separate config class and import it. I still have to be careful that the new config class doesn't get picked up by someone's component scan, but that's also the case for auto-conf class pointet to by spring.factories. EDIT: Oh my! Just now I realize you're the guy from a great and very helpfull talk.Impatiens
Yeah, for that you could do @Import(ComponentA.class, ComponentB.class) on your auto-configuration or any configuration that makes sense in that context. The key aspect is to describe what's happening rather than relying on component scan that's more suited to applications.Nonconformist
If this is the rule, why Spring not just ban @ComponentScan in @AutoConfiguration? It's easy to misuse this feature and very intuition. Because define these config class one by one vs just @ComponentScan them, most developer will choose the 2nd way :)Peirsen

© 2022 - 2024 — McMap. All rights reserved.