-
Notifications
You must be signed in to change notification settings - Fork 41.6k
Description
I would like to be able to generate configuration metadata using lombok @Value annotations and Constructor Binding.
Background
In our projects we have adopted ConstructorBinding but perhaps differently from what was envisaged at Spring :-).
To avoid collisions we place all of our properties under a single tag: "application" (we use yaml).
Under here we have application specific configuration properties.
In Java we have one parent class "ApplicationProperties" using ConstructorBinding that contains the sub properties.
@ConfigurationProperties("application")
@ConstructorBinding
@Value
public class ApplicationProperties {
String name;
Service1Properties service1;
Service2Properties service2;
}And then each sub system configuration only needs the @Value annotation, for example:
@Value
public class Service1Properties {
String prop1;
Duration prop2;
}Java field names need to match the property name but this gives us a number of benefits:
- No need to specify property keys in multiple files with ConfigurationProperties.
- reduces errors
- easier refactoring
- All classes are Immutable
- Java properties classes reflect properties files structure
- Easier to test and validate at startup
- Common values from the top level (like name/environment) can be available when creating subsystem beans.
- Clean properties classes: only one annotation: @Value
We only inject the Application Properties in one place (where we create beans). If we need subsystem properties we either inject that or expose it as a bean.
But there is one major downside, generation of metadata from spring-boot-configuration-processor.
Existing Code
I have looked at how the annotation processor works and I see there is support for @Data and @Getter/Setter.
I experimented with that a bit, but see that I always need a real "AllArgsConstructor" - the lombok one does not work.
This is normal I guess since they are both annotation processors and so run order cannot be guaranteed
I tried adding @Value to the existing code and by creating similar tests everything was fine but in our case it still won't generate the metadata because the class is not annotated with @ConfigurationProperties.
What I've done so far is to put them in by hand, generate them, and then put them in additional-spring-configuration-metadata.json
But it soon gets out of sync. It'd be great to support this, but I can see how it would be a lot of work with the existing code base.
Maybe if it was undergoing major changes in future it could be considered?
Example project based on start.spring.io attached. See DemoApplicationTests.java