-
Notifications
You must be signed in to change notification settings - Fork 706
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
ConfigurationPropertiesRebinder not compatible with @ConstructorBinding when constructed in bootstrap #844
Comments
We are not going to support rebinding |
I'm unable to reproduce the error log. When I do it, it value doesn't update and no exception is logged. Can you provide a complete, minimal, verifiable sample that reproduces the problem? It should be available as a GitHub (or similar) project or attached to this issue as a zip file. |
https://github.com/symposion/spring-test (The master branch) I've created an immutable @ConfigurationProperties class that I have no intention of mutating, I'm not explicitly refreshsing /rebinding anything, and the app fails to startup because internally Spring cloud is rebinding all the properties from the bootstrap context. I understand why that's done, but at the very least this is surprising and worth calling out in the docs as a potential "gotcha". A nicer alternative might be to just ignore properties beans that are constructor-bound when rebinding with a warning in the logs rather than a hard fail; or make the post-bootstrap rebinding optional somehow? |
This only applies to constructor binding beans that are created in a bootstrap configuration. Considering this is relatively uncommon and I"m not sure how to distinguish if it was created in bootstrap or not, I'm going to mark this as waiting for votes. |
FWIW, I just ran into this problem |
Pretty sure I encountered this as well. I'm trying to create something like @ConstructorBinding
@ConfigurationProperties(AwsParamStoreProperties.CONFIG_PREFIX)
data class AwsParamStoreProperties(
val region: String? = null,
val endpoint: URI? = null,
val name: String? = null,
val enabled: Boolean = true
) {
companion object {
const val CONFIG_PREFIX = "aws.paramstore"
}
} It loads the parameters from SSM, but when the application context tries to import the @ConfigurationProperties(AwsParamStoreProperties.CONFIG_PREFIX)
class AwsParamStoreProperties {
var region: String? = null
var endpoint: URI? = null
var name: String? = null
var enabled: Boolean = true
companion object {
const val CONFIG_PREFIX = "aws.paramstore"
}
} But then we lose immutability. Using Spring Boot 2.5.1, spring-cloud-context 3.0.3. |
Are there any other workarounds? |
Using Hoxton.SR8
If you define an @ConfigurationProperties class that uses @ConstructorBinding, attempts to rebind it using ConfigurationPropertiesRebinder will fail with an exception from ConfigurationPropertiesBindingPostProcessor: ""Cannot bind @ConfigurationProperties for bean XXXX Ensure that @ConstructorBinding has not been applied to regular bean"
This is especially problematic because Spring Cloud Context rebinds all ConfigurationProperties classes that have been used in the bootstrap context in order to ensure that property changes during the bootstrap phase are picked up. Looking at the code, it's not clear to me that there's a simple fix for this: the rebinder fundamentally assumes that the properties bean is mutable. In order to support immutable properties classes I guess it would need some sort of proxy in the middle to allow the properties bean to be re-constructed without having to reinject it into every dependent bean.
The text was updated successfully, but these errors were encountered: