Hello, as in discusion on Gitter there is an issue after update from 3.0.3 to 3.0.4 with @ConfigurationProperty and @Component on bean.
Repro repo: https://github.com/Azbesciak/spring-3-configuration-prop-issue/tree/spring-boot-3.0.4-config-prop-component-issue (please notice branch spring-boot-3.0.4-config-prop-component-issue)
I suppose it existed also in 3.0.0 (that repo contains the example I also reported - https://github.com/spring-projects/spring-boot/issues/33509) @wilkinsona also mentioned https://github.com/spring-projects/spring-boot/issues/34407
Comment From: hho
I (probably) hit the same issue when upgrading to 3.0.4. Had a Kotlin data class with var fields and default values and wanted to apply @ConfigurationProperties like this:
@Bean
@ConfigurationProperties("event-hubs.producer")
fun eventHubProducerProperties() = EventHubProducerProperties()
In 3.0.0 this didn't work, then in 3.0.2 it did, and now in 3.0.4 it doesn't work again. I guess that fixing #34407 led to a regression for #33710?
I stepped through it with a debugger: there are two instances created, one gets the properties injected, but the other one is used for the rest of the application context.
Comment From: philwebb
@Azbesciak You sample has the SomeConfig class annotated with @Component which makes Spring attempt to create it as a regular bean, rather than a configuration properties bean. If you remove @Component from SomeConfig and add @ConfigurationPropertiesScan to your DemoApplication class then things work.
Comment From: philwebb
@hho I expect your problem is similar. If you define a @Bean method then you are in control of creating the bean and constructor binding cannot be used. You could try @EnableConfigurationProperties(EventHubProducerProperties.class) if you want to create the EventHubProducerProperties instance using constructor binding.
If that doesn't work, please provide a sample that I can take a look at.
Comment From: Azbesciak
@philwebb thank you for the quick reply.
My question is: is it a temporary solution or you stated that and no step back?
You know, that once occurred, I have tens of beans like that, some of them are @Bean, some of them are @Component, some just have @Bean and @ConfigurationProperty in configuration - not declared on class directly.
If it is permanent, I need to know that, but... you know, legacy, backward compatibility... not a good way to introduce in a patch release. Not a good way at all since it was working like this for as long as I remember, and it occurs even in tutorials.
Comment From: philwebb
Sorry, I think I messed up. I assumed that Kotlin data classes were immutable, but it looks like they can have setters. I'll need to change this logic https://github.com/spring-projects/spring-boot/blob/285097d746fbff1ce18a64d7c45a297cc196e0d6/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/DefaultBindConstructorProvider.java#L109
Comment From: Azbesciak
As I remember they can be immutable in spring boot, and still it is possible to use them as properties with @ConfigurationProperty, but to do that some special freamework configuration is required. @sdeleuze will know better :)
But yes, in general, Kotlin data class can be mutable.
Comment From: hho
OK, I took an hour to minimize my repro, and now I'm four minutes late :smile:
Thank you both!
Comment From: hho
@wilkinsona Sorry, but I think that title is slightly misleading: The current issue affects all mutable data classes used with @ConfigurationProperties, not just the @Component annotated ones.