The new Certification Class of Learn Spring Security is out:


1. Introduction

One of the handy features of Spring Boot is externalized configuration and easy access to properties defined in properties files.

An earlier article described various ways in which this can be done and in this article, we’re going to explore the @ConfigurationProperties annotation in greater detail.

2. Setup

The setup for this article is fairly standard. We start by adding spring-boot-starter-parent as the parent in our pom.xml:

<!-- Inherit defaults from Spring Boot -->
    <relativePath/> <!-- lookup parent from repository -->

The latest version of Spring Boot can be found on the maven central here.

In order to be able to validate properties defined in the file, we would need a JSR-303’s implementation. hibernate-validator is one of them. Let’s add it to our pom.xml as well:


Depending on the type of application and the environment running, we might need to add one or more additional dependencies. The reference page has details about the same, and the latest version of hibernate-validator can be found here.

We shall take the example of a hypothetical class which has configuration properties related to a mail server to understand the full power of this annotation:

public class ConfigProperties {

    public static class Credentials {
        private String authMethod;
        private String username;
        private String password;

       // standard getters and setters
    private String host;
    private int port;
    private String from;
    private Credentials credentials;
    private List<String> defaultRecipients;
    private Map<String, String> additionalHeaders;
    // standard getters and setters

3. Binding the Configuration Properties

According to the official documentation, it is recommended to isolate the configuration properties into a separate POJO annotated with @ConfigurationProperties, so let’s start by doing that:

public class ConfigProperties {
    // previous code

We also have added the @Configuration annotation for Spring to be able to find this bean and make it a candidate for injection.

The annotation works best when we have hierarchical properties that all have the same prefix, so we mention the prefix too as a part of the annotation. We can also optionally define a custom source where we’re storing these properties, else the default location (

We can also optionally define a custom source where we’re storing these properties, else the default location ( is looked up. So we now add the above annotations to the existing properties class:

@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {
    // previous code

That’s it! Now any properties defined in the property file that has the prefix mail and the same name as one of the properties are automatically assigned to this object.

Also, by default, a relaxed binding scheme is adopted for the binding, so all of the following variations are bound to the property authMethod of the Credentials class:


Similarly, List and Map properties can also be bound. Here’s a sample properties file that binds correctly to our ConfigProperties object defined earlier:

#Simple properties
[email protected]
[email protected]

#List properties
mail.defaultRecipients[0][email protected]
mail.defaultRecipients[1][email protected]

#Map Properties

#Object properties

4. Property Validation 

One of the handy things that this annotation provides the is the validation of properties using the JSR-303 format. This allows for all sorts of neat things like checking that a property is not null:

private String host;

We can also check the minimum and maximum length of a String property:

@Length(max = 4, min = 1)
private String authMethod;

Or enforce the minimum and maximum value of an Integer property:

private int port;

And finally, we can also make sure that a property matches a certain pattern by defining a regex for the same. This has been done for email, as an example:

@Pattern(regexp = "^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,6}$")
private String from;

This helps us reduce a lot of if – else conditions in our code and makes it look much cleaner and concise.

If any of these validations fail then the main application would fail to start with an IllegalStateException till the incorrect property is corrected.

Also, it is important that we declare getters and setters for each of the properties as they’re used by the validator framework to access the concerned properties.

5. Conclusion

In this quick tutorial, we explored the @ConfigurationProperties annotation and also saw some of the handy features it provides like relaxed binding and Bean Validation.

As usual, the code is available over on Github.

Go deeper into Spring Security with the course:


  • sanjeev kumar

    Very nice article. Could you please share how to load properties files which are located in external directories and sub directories.
    I tried
    @PropertySource(value=”file:W:\myHome\Env\conf, W:\myHome\Env\conf\spring)
    I am only providing the path & under that path are various properties file which I would like to load.

    Also in I did this
    spring.config.location=file:W:\myHome\Env\conf, W:\myHome\Env\conf\spring
    But it is not working.
    Could you please suggest.
    Thank you

    • Grzegorz Piwowarek

      It’s definitely possible. On your place, I would try to setup PropertySourcesPlaceholderConfigurer bean properly. Then it should be easy to access those properties

      • sanjeev kumar

        Thank you. I tried this
        public static PropertySourcesPlaceholderConfigurer propertySources() {
        PropertySourcesPlaceholderConfigurer ppConfig = new PropertySourcesPlaceholderConfigurer();
        Resource[] resources = new ClassPathResource[]
        { new ClassPathResource( “W:\myHome\Env\conf\spring” ) };
        ppConfig.setLocations( resources );
        return ppConfig;
        Class path resource W:/myHome/Env/conf/spring cannot be opened because it does not exist. The path is correct.

        • Grzegorz Piwowarek

          Try FileSystemResource instead of ClassPathResource. It’s not the classpath anymore 🙂