Closed ChristianIvicevic closed 1 month ago
This might be related to the recent constructor binding changes that we made. Check out this section of the release notes for details.
Do you get correct metadata if you change @ConfigurationProperties
to @ImmutableConfigurationProperties
?
@philwebb Using @ImmutableConfigurationProperties
actually causes the metadata file to not be created at all or being deleted if it existed previously.
Yep, that part is an oversight and we’ll use this issue to fix it. Add @ConstructorBinding instead.
@snicoll I can confirm, @ConstructorBinding
and @ConfigurationProperties
work together as expected for the time being.
I'd like us to reconsider having @ImmutableConfigurationProperties
at all. If we improve our current setup in the future so that @ConstructorBinding
is not necessary for the idiomatic setup, the annotation will become irrelevant. Also, we created @ConstructorBinding
to be able to be explicit about things and having @ImmutableConfigurationProperties
is hiding that a bit again (not the fact the constructor will be used but the fact a unique constructor if present will be used).
I can see two problems:
@ImmutableConfigurationProperties
and the class has two constructors you have to put @ConstructorBinding
again. If you don't, JavaBean properties binding is used which feels quite odd@ConstructorBinding
then you have @ImmutableConfigurationProperties
+ @ConstructorBinding
again. This reduce the relevance of the dedicated annotation in this caseAll in all, I don't think it feels very consistent with our move of being more explicit about this. Flagging for team attention to see what the rest of the team thinks.
If you use @ImmutableConfigurationProperties and the class has two constructors you have to put @ConstructorBinding again. If you don't, JavaBean properties binding is used which feels quite odd
I think it should throw an exception. It's the same as adding @ConstructorBinding
on the type then having an ambiguous constructor.
If you do add @ConstructorBinding then you have @ImmutableConfigurationProperties + @ConstructorBinding again. This reduce the relevance of the dedicated annotation in this case
This is true, but it doesn't seem any worse than having @ConfigurationProperties
and @ConstructorBinding
. I also think that 90% of users won't have multiple constructors.
When updating the tests I found needing two annotations really clunky and I quite liked @ImmutableConfigurationProperties
. In a lot of ways it's like @RestController
. You could argue that @Controller
and @ResponseBody
are more explicit, but I like the convenience of @RestController
.
In a lot of ways it's like @RestController.
I can see how it's grouping one annotation with two features but there is a major difference IMO. With @RestController
it has an impact on all mapping methods of the class and it makes sure you don't end up returning the name of a view if you forget to add @ResponseBody
to one of them. This one is about a single use (the constructor to use or the fact of using a constructor at all).
I agree with the convenience for the 90% use case but I am still wondering about whether we should promote it as a first class citizen.
I have another concern with the ImmutableConfigurationProperties
annotation: its name.
It tends to imply that it is supposed to be used on immutable classes only. Or worse, that annotating a class with this annotation makes the class immutable.
But it isn't the case. Using the annotation on a class which has setters, or var
in Kotlin , doesn't cause any problem.
I understand that constructor bindings makes it possible to create immutable configuration properties classes, and that making that possible was the primary goal of constructor binding, but still, the name is confusing. ConstructorBoundConfigurationProperties
would be a more correct name, IMHO.
Thanks for the feedback, @jnizet. We've decided to remove @ImmutableConfigurationProperties
.
Thank you for clarifying the usage with both annotations and removing the immutable annotation. Closing this issue.
No problem, @ChristianIvicevic. I'm going to re-open this issue as we'd like to use it to track adding support to the annotation processor for finding @ConfigurationProperties
when it's used as a meta-annotation.
I don't really remember what we have in mind for this but the annotation processor is triggered by specific annotations and has no concept of meta annotations. We're also outside the boundary of our annotation utilities that handle composed and meta-annotations for us automatically so, even if we changed our processor to react to any annotation, we'd still need significant work to make it work in the API the AP uses.
I've added a note in the reference guide https://github.com/spring-projects/spring-boot/commit/9817201833503b157182db288aed7b1016c5f997.
In my project I have the following setup:
build.gradle.kts
:ServiceApplication.kt
ServiceConfigurationProperties.kt
This setup works with
v2.2.0.M6
and yields the followingspring-configuration-metadata.json
as expected (and enabling IntelliJ auto completion and hints in the yaml configuration files):Unfortunately when upgrading to
v2.2.0.RC1
theproperties
array ends up being empty in the json file: