-
Notifications
You must be signed in to change notification settings - Fork 40.2k
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
Support constructor binding on 3rd party classes #23607
Comments
@snicoll just to clarify, in this suggestion the annotation processor will or will not create the meta-data in order to have auto-complete in the yaml editor in intellij/eclipse? In general, the reason I opened the original ticket was:
|
It's another go to what was reverted so the answer to your question is obviously yes. That being said, we may or may not make it. Binding to third party types (especially with metadata) is not the primary use case and while I have some sympathy for being able to bind types that don't know anything about Spring, it feels to me this is less valid when you want proper metadata as this is a concept that's definitely linked to Spring Boot. Your current approach does not provide description and default values for keys. IMO, if metadata is important, that's something you should make sure is generated as well. |
@snicoll that makes sense, thanks for the clarifications. |
Not sure if it could be an alternative "solution", but in the library, we create an interface which contains declaration of getters only. Then in the consumer module, the data class implements the interface with constructor binding. interface MyConfig {
val confA: Int
}
// in consumer module
@ConfigurationProperties(my.module.config)
data class AppMyConfig(
override val confA: Int
) : MyConfig |
Please could I add a plus 1 for this feature. My team prefer to use constructor binding for Configuration Properties classes so that we can rely on the immutability of the object. It would be great if we could use bean construction methods for these objects and benefit from the same metadata. |
@david-grew-activeviam I think you don't need anymore this feature because since Spring Boot 3 you don't need to put anymore @ConstructorBinding annotation on classes and Spring chooses the right constructor to use by reflection. |
@frecco75 - I don't think this addresses the issue. Even in Spring 3 I don't believe you can have an immutable Configuration Properties object (i.e. without setters) and create it using a method in an |
We had a first attempt in #23172 that we decided to revert due to a number of inconsistencies the proposal brings.
Using a declarative model as proposed in #23172 means that we need to figure out whether the user expects the binder to use constructor binding or regular JavaBean conventions. Ignoring that a Kotlin data class (or Java record) could provide us extra metadata, we didn't manage to find an acceptable solution for
@EnableConfigurationProperties
.Binding to 3rd party classes so far has been a niche. The way to do this is by declaring a
@Bean
method with@ConfigurationProperties
. For a constructor-based approach, this isn't possible but we could provide a shortcut where one needs to inject a component we'd register in the context, something like:The definition above would bind
MyCustomObject
using theexample.acme
namespace. Rather than aClass
you may provide a supplier for the instance and/or a mode to determine how you want the binder to operate.Doing things this way means that the annotation processor won't be able to easily detect that it has to generate properties for this. Considering the metadata isn't going to contain default values and description anyway (since the code sits in a different module), this can be considered as a limitation (and one of the reason we may want to keep this niche).
The text was updated successfully, but these errors were encountered: