Reputation: 1650
I have a SpringBoot 2.1.7.RELEASE project with gradle. I'm getting an error when I try to use @ConfigurationProperties
The property that I'm trying to bind is existing in my application-default.properties and if I run the project using Itellij I can see that the property is ingested in my component.
If I enable @EnableConfigurationProperties I got an error.
My application-default.properties
app.forwarding-endpoint=localhost:8080
My AppProperties.java
@ConfigurationProperties(prefix = "app", ignoreUnknownFields = false)
@Validated
@Data
public class AppProperties {
@NotBlank
@Pattern(regexp = "^(.+):\\d+$")
private String forwardingEndpoint;
}
My Application.java
@SpringBootApplication
@EnableConfigurationProperties(AppProperties.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application .class, args);
}
}
My component that is using the property:
public MyComponent(@Value("${app.forwarding-endpoint}") String forwardingEndpoint) {
log.info("Forwarding endpoint {}", forwardingEndpoint);
}
The error that I get is:
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'app' to com.config.AppProperties failed:
Property: app.forwardingEndpoint
Value: null
Reason: must not be blank
What am I missing?
Upvotes: 6
Views: 64150
Reputation: 821
The cause is in the order of initialization. You did not fill AppProperties but start to use it in components. You need to annotate this class also as a component but it's not a good approach from point of view of an architecture.
The concept of @ConfigurationProperties is quite raw for Spring and without some manipulations, you will quite difficult to force it to work correctly. I propose a simple 'trick' (or 'another approach'):
@Data
public class AppProperties {
@NotBlank
@Pattern(regexp = "^(.+):\\d+$")
private String forwardingEndpoint;
}
(I think the place of @validated is not in the entitity/DO).
And place in your @Configuration next code:
@Bean
@ConfigurationProperties(prefix = "app", ignoreUnknownFields = false)
public AppProperties setAppProperties() {
return new AppProperties();
}
And next, you can inject AppProperties bean in any component.
Upvotes: 4