StackTips
 5 minutes

Validating @ConfigurationProperties in Spring Boot

By Nilanchala @nilan, On Feb 18, 2024 Spring Boot 1.32K Views

Did you know you can validate configuration properties at spring application startup with @ConfigurationProperties annotation? This can validate properties on application startup when used in conjunction with JSR-380 bean validation annotations such as @Min, @NotNull.

List of built in validation constraints in JSR 380

The @Validated annotation at the class level in conjunction with @ConfigurationProperties is used to enable validation.

@Getter
@Setter
@Component
@Validated
@ConfigurationProperties(prefix = "importer.service")
public class ImporterProperties {

    @NotNull
    private String filePath;

    @Min(3)
    private int threadPoolSize;
}

application.properties

importer.service.filePath=/nfs/files
importer.service.threadPoolSize=1

It will bind these properties to the ImporterProperties object and validate them at application startup, thus ensuring the application doesn't run with invalid configurations.

If the validation fails it will result in BindException as shown below:

***************************
APPLICATION FAILED TO START
***************************

Description:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'importer.service' to com.stacktips.app.config.ImporterProperties failed:

    Property: importer.service.threadPoolSize
    Value: "1"
    Origin: class path resource [application.properties] - 4:35
    Reason: must be greater than or equal to 3


Action:

Update your application's configuration

Please note, for this validation to work, we need to have a JSR-380 implementation like Hibernate Validator on your classpath and we need to explicitly enable the configuration properties validation.

implementation 'org.springframework.boot:spring-boot-starter-validation'

Considerations for using Records

Starting with Spring Boot 2.6 and Java 16 you can use record classes with @ConfigurationProperties. But there are few things you need to consider when using records.

@Validated  
@ConfigurationProperties(prefix = "importer.service")  
public record ImporterProperties(  
        @NotNull String filePath,  
        @Min(3) int threadPoolSize) {  
}

Notice that, you cannot use @Componenet annotation when using records. Your IDE will show annotated with @ConstructorBinding but defined as Spring component error.

To fix this, we need to remove the @Component annotation and @EnableConfigurationProperties or explicitly do the bean registration using the @Bean annotation in one of your @Configuration class.

For example:

@EnableConfigurationProperties(ImporterProperties.class)  
@SpringBootApplication  
public class MyApplication {  

    public static void main(String[] args) {  
       SpringApplication.run(MyApplication.class, args);  
    }  

}
nilan avtar

Nilanchala

I'm a blogger, educator and a full stack developer. Mainly focused on Java, Spring and Micro-service architecture. I love to learn, code, make and break things.