Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better document new @AutoConfiguration annotation #35044

Closed
xak2000 opened this issue Apr 18, 2023 · 5 comments
Closed

Better document new @AutoConfiguration annotation #35044

xak2000 opened this issue Apr 18, 2023 · 5 comments
Assignees
Labels
type: wiki-documentation A documentation update required on the wiki
Milestone

Comments

@xak2000
Copy link
Contributor

xak2000 commented Apr 18, 2023

After reading the documentation and javadocs for 3.0.x, it's still unclear what the difference between the new @AutoConfiguration annotation and old @Configuration annotation.

It's clear that @AutoConfiguration is meta-annotated with @Configuration(proxyBeanMethods = false). But the question is: was the only reason to have this new @AutoConfiguration annotation is to promote "proxyBeanMethods = false by default" rule? And probably also to mark a class for tooling.. Or there are some other reasons and consequences?

I tried to search, but didn't found any discussions about motivation of introducing this annotation, except this #29870, but it's pretty undetailed.

Basically, will a class annotated with @AutoConfiguration annotation be 100% functionally equivalent to the same class, but directly annotated with @Configuration(proxyBeanMethods = false)?

What if a class, that is listed in the META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports file, will be annotated with @Configuration annotation (contrary to documentation)? Will it still be found and properly registered in Spring Boot 3.x? Or will it be ignored?

What if a class, that is annotated with @AutoConfiguration annotation will not be listed in the META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports file, but instead will happen to be component-scanned? Will it be registered as a bean (because it is meta-annotated with @Configuration) or will it be specifically filtered out to protect from accidental component-scanning of autoconfigurations? It would be very cool, if yes, or even better to not just filter-it-out, but to force the app startup to fail or at least print a warning, as this situation often leads to very subtle bugs.

The migration guide also states that @AutoConfiguration should be used instead of @Configuration for top-level autoconfiguration classes, but it doesn't explain what if someone doesn't follow this rule and still continues to use @Configuration annotation on a top level autoconfiguration class? It's especially important for libraries (boot-starters) that want to be backward-compatible with both 2.x and 3.x.

Probably, it's worth to mention in both migration-guide and official documentation that @Configuration will still work (if that is true) and also to slightly describe the motivation of introducing @AutoConfiguration annotation. And, if some additional filters/logic/etc is applied only to @AutoConfiguration-annotated classes, but not to @Configuration-directly-annotated classes, then certainly to mention it too.

Also, both documentation and migration guide doesn't describe what will happen in 2.7.x if both spring.factories and META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports files are present and contain the same autoconfiguration class. It would be useful to have this setup for a library (a boot-starter) during migration period because this library could be used from:

  • already migrated to 3.x microservices (so, only new file will be read);
  • migrated to 2.7 microservices (so, both spring.factories and new file will be read - here is the confusion);
  • still-on-2.6 microservies (so, only spring.factories will be read).

It would be possible only if 2.7.x somehow ignores one of 2 declarations. It would be useful to have a description of the behavior for this situation in the 2.7 migration guide (and probably 2.7.x docs).

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 18, 2023
@philwebb philwebb added type: documentation A documentation update and removed status: waiting-for-triage An issue we've not yet triaged labels Jun 7, 2023
@philwebb philwebb added this to the 3.0.x milestone Jun 7, 2023
@philwebb philwebb modified the milestones: 3.0.x, 3.1.x Nov 8, 2023
@wilkinsona wilkinsona added type: wiki-documentation A documentation update required on the wiki and removed type: documentation A documentation update labels May 20, 2024
@wilkinsona wilkinsona modified the milestones: 3.1.x, 3.1.12 May 20, 2024
@wilkinsona
Copy link
Member

wilkinsona commented May 20, 2024

I've made some small updates, both to the 3.0 migration guide and to the 2.7 release notes.

I think the existing reference documentation already covers quite a bit of this. For example, it explains that @AutoConfiguration is meta-annotated with @Configuration "making auto-configurations standard @Configuration classes" and that you must "make sure that they are defined in a specific package space and that they are never the target of component scanning."

@xak2000
Copy link
Contributor Author

xak2000 commented May 20, 2024

@wilkinsona

I think the existing reference documentation already covers quite a bit of this. For example, it explains that @AutoConfiguration is meta-annotated with @Configuration "making auto-configurations standard @Configuration classes" and that you must "make sure that they are defined in a specific package space and that they are never the target of component scanning."

Yes, it explains that @AutoConfiguration is meta-annotated with @Configuration. But it doesn't explain what is the difference between them. What will happen if I will ignore @AutoConfiguration annotation and will annotate all my auto-configuration classes with @Configuration? Something will not work?

The documentation doesn't answer this questions:

Basically, will a class annotated with @AutoConfiguration annotation be 100% functionally equivalent to the same class, but directly annotated with @Configuration(proxyBeanMethods = false)?

What if a class, that is listed in the META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports file, will be annotated with @Configuration annotation (contrary to documentation)? Will it still be found and properly registered in Spring Boot 3.x? Or will it be ignored?

What I want to see in the documentation (and not just migration guides) is something like this:

Any @Configuration-annotated class is eligible to serve as auto-configuration. The @AutoConfiguration annotation is just for convenience of declaration and for tooling.

Why is that important: because we (the whole community) have millions of already written code, libraries, starters, that use @Configuration-annotated classes as auto-configurations.

The phrase "making auto-configurations standard @Configuration classes" doesn't mean to me that vice versa is also true (i.e. standard @Configuration classes are still considered as auto-configuraton candidates if located in the AutoConfiguration.imports file).

Therefore, according to the current documentation, it looks like only @AutoConfiguration-annotated classes could be added to AutoConfiguration.imports file and will be eligible to be auto-configuraton candidates. This could grearly confuse new people. It greatly confused even me and I use Spring for 10 years now.

@xak2000
Copy link
Contributor Author

xak2000 commented May 20, 2024

Also I found this comment: eventuate-foundation/eventuate-common#130 (comment)
And this: eventuate-foundation/eventuate-common#130 (comment)

So, now I really wonder if my conclusion that @Configuration should still work if class is added to AutoConfiguration.imports is true... 😱

@wilkinsona
Copy link
Member

now I really wonder if my conclusion that @Configuration should still work if class is added to AutoConfiguration.imports is true

Those comments are incorrect and it will continue to work.

I still don't think we should go into any more details in the documentation and my feeling is that it will overwhelm the reader with too much information. If you would really like to see a change, please propose something in a pull request and we will review it. Perhaps it won't look as bad as I suspect when we see it.

@xak2000
Copy link
Contributor Author

xak2000 commented May 20, 2024

Those comments are incorrect and it will continue to work.

Ok, thank you for the confirmation. I'm glad that it will work!

But, see? This confuses people. Not only me. 😸

Because documentation doesn't explicitly says that @Configuration inside AutoConfiguration.imports is supported too. And the fact that @AutoConfiguration is meta-annotated with @Configuration doesn't confirm anything because how could I know that the auto-configurations loader doesn't explicitly check for @AutoConfiguration annotation presense?

I disagree about "too much information" because it is very important information that I as a reader was trying to find (unsucessfully) and was forced to read the source code and do experiments to understand how it works (and if it works at all). But the problem with experiments is that even if they confirm that it works, it doesn't mean that it is just a coincidence (an implementation details) and will be broken in the next release. On the other hand, if it is documented, then I could trust this behavior.

Ok, I will try to do a pull request, thanks for the idea! I just usually hesitate to do PRs related to the docs because:

a) I'm stull not 100% sure if this behavior is expected/intended (because it is NOT documented).
b) English is not my native language as you probably notcied and I'm sure my description in the docs will contain many grammatical mistakes. :( But probably the person who will do a commit could fix this. I don't think it will be long text. Just a few words to declare the fact that @Configuration is still officially supported to get rid of the confusion.
c) I'm not sure how to describe the reason why @AutoConfiguration was introduced in the first place. I tried to find any detailed discussion on this topic, but nothing! To me it's an overkill. @Configuration was working perfectly fine. Maybe it would make more sense if @AutoConfiguration was not meta-annotated with @Configuration. In this case it would solve the problem of classpath scanning and mistakenly applying auto-configurations that are not supposed to be classpath scanned. But nope. This problem still exists. So, to me the reason of introducing a new annotation is still a bizarree..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: wiki-documentation A documentation update required on the wiki
Projects
None yet
Development

No branches or pull requests

4 participants