spring-projects / spring-boot

Spring Boot
https://spring.io/projects/spring-boot
Apache License 2.0
74.95k stars 40.65k forks source link

Support scanning @Value annotation for metadata in reguler @Component when using spring-boot-configuration-processor #42429

Closed frode-carlsen closed 3 weeks ago

frode-carlsen commented 3 weeks ago

Quite often separate classes with configuration details aren't used in Spring Boot code. Instead @Value parameters are injected directly into for example @Component or @Service objects. If applying @ConfigurationPropertiesto such classes a warning is issued against this.

It would be very helpful to generate metadata for classes that have injected properties, but are not @ConfigurationProperites classes, as in the following case

@Component
public class SomeComponent {
  public SomeComponet(AnotherBean anotherBean, @Value("some.config.property:true") someProperty){
  }
}

I'm suggesting the processor should pick up the "some.config.property" with default value true and generate the appropriate metadata json file for this. It would greatly simplify processing and validation of configuration properties without enforcing a particular separation of properties and components.

wilkinsona commented 3 weeks ago

Thanks for the suggestion but @Value isn't really a suitable source for generating configuration property metadata. For example, there's no way to provide a description of the property. It's also possible that multiple @Value annotations will consume the same property where as @ConfigurationProperties is intended to provide a canonical source for the definition of a property. With multiple consumers of the same property, merging may become necessary which adds a lot of complexity, particularly when it's possible for @Value to consume the same property as two different types.

I think it's also worth noting that @Value is a Spring Framework feature. If some scanning of @Value and metadata generation were to be performed, it would be better as an additional Spring Framework feature, particularly as Spring Boot's property metadata format isn't a good fit for the reasons described above.

frode-carlsen commented 3 weeks ago

That's a shame, it pretty much cuts down the usefulness of the metadata feature (we have over 1000s properties with literally 10000s of configuration values). Giving the ability to scan @Value significantly reduces the amount of boiler-plate code to define properties.

Some are consumed by multiple consumers anyway with ConfigurationProperties, in a large system of multiple microservices. Although this may not be what was intended, it's real world usage where reuse of configuration property keys but separation of code dependencies allows for better separation of responsibilities. The ability to opt-in to scanning @Value would be much appreciated.

(our main benefit is to see which properties are no longer in use, and which are available - which we then get through the IDE)

wilkinsona commented 3 weeks ago

As I said above, if you would like to see scanning of @Value and production of some metadata, that would be a Spring Framework feature. If this is something that you would like to pursue, you could request it in their issue tracker.

In addition to the reasons already listed above, Boot's metadata format cannot be used with @Value as the property names that can be consumed with @Value do not necessarily adhere to the naming conventions for configuration properties and aren't subject to Spring Boot's relaxed binding. This means that any metadata generated from @Value could contain property names in a format that isn't expected by consumers of Spring Boot's property metadata.

frode-carlsen commented 3 weeks ago

Ok, raised this issue https://github.com/spring-projects/spring-framework/issues/33591