All Articles

Externalized Configuration of Spring Boot application with @ConfigurationProperties

Spring boot gives you the ability to Externalize your configuration in different ways. In this article, we explore how to define and use external configurations in Spring Boot with @ConfigurationProperties annotation.

Simple Properties

For small and simple structure of properties or yml files, we use @value annotation.

For example :

@Value("${app.email}")  
private String email;  
@Value("${app.name}")  
private String name;

properties file :

#Simple properties  
app.email=contact@chrouki.com  
app.name=demo

The official documentation advises to isolate the configuration properties in separate POJOs.

If you define a set of configuration keys for your own components, we recommend you group them in a POJO annotated with @ConfigurationProperties

That’s what it looks like our POJO for now :

@Configuration  
@ConfigurationProperties("app")  
public class AppProperties {  
  
    @Value("${email}")  
    private String email;  
	@Value("${name}")  
    private String name;
	
	//getters and setters

}

We use @Configuration so that Spring creates a Spring bean in the application context. Spring Boot application loads configuration properties from application.properties file located in the classpath by default. Otherwise, we need to use @PropertySource to define location of our file properties.

We add prefix app to @ConfigurationProperties , so Spring will automatically bind any property defined in our property file that has the prefix app and the same name as one of the fields in the ConfigProperties class.

Note: @ConfigurationProperties supports both .properties and .yml file.

Spring Boot uses some relaxed rules for binding, the following properties names can all be used:

app.appName=demo
app.app-name=demo
app.app_name=demo
APP.APPNAME=demo

Nested Properties

We can have nested properties in Lists, Maps, and complex objects as Classes.

Let us create a new Author and Site classes to use for some nested properties.

Author.java :

public class Author {  
    private String name;  
	private String description; 
	//getters and setters 
}

Site.java :

public class Site {  
    private String host;  
	private String ip;  
	private String port;
	//getters and setters 
}

We also update our AppProerties POJO to use a List, a Map , a complex Object Author, also a multiple complex Object Site with différent values :

@Configuration  
@ConfigurationProperties("app")  
public class AppProperties {  
  
    private String email;  
    private String appName;  
  
	private List<String> contacts;  //list 
  	private Author author;  //complex Object
	private HashMap<String, String> site;  //Map 
	private HashMap<String, Site> sites; //Multiple value of complex Object 

The following properties file will set all the fields:

#Simple properties  
app.email=contact@chrouki.com  
app.appName=demo  
  
#List properties  
app.contacts[0]=contact@chrouki.com  
app.contacts[1]=admin@chrouki.com  
  
#Object properties  
app.author.name=Tarik  
app.author.description=Developer  
  
#Map Properties  
app.site.host=chrouki.com  
app.site.ip=127.0.0.1  
app.site.port=8080  
  
#Multiple nested object  
app.sites[first].host=chrouki.com  
app.sites[first].ip=127.0.0.1  
app.sites[first].port=8080  
  
app.sites[second].host=another.chrouki.com  
app.sites[second].ip=127.0.0.1  
app.sites[second].port=9090

equivalent in YAML file :

aapp:  
  #Simple properties  
  email: contact@chrouki.com  
  appName: demo  
  #List properties  
  contacts:  
    - contact@chrouki.com  
    - admin@chrouki.com  
  #Object properties  
  author:  
    name: chrouki  
    description: Developer  
  #Map Properties  
  site:  
    host: chrouki.com  
    ip: 127.0.0.1  
    port: 8080  
  #Multiple nested object  
  sites:  
    first:  
      host: chrouki.com  
      ip: 127.0.0.1  
      port: 8080  
    second:  
      host: another.chrouki.com  
      ip: 127.0.0.1  
      port: 9090

Demo

If we inspect our bean AppProperties during starting our application :

@SpringBootApplication  
public class SpringBootPropertiesApplication {  
  
    public static void main(String[] args) {  
        SpringApplication.run(SpringBootPropertiesApplication.class, args);  
  }  
  
    @Autowired  
  private AppProperties appProperties;  
  
  @Bean  
  public CommandLineRunner commandLineRunner(ApplicationContext ctx) {  
        return args -> {  
            System.out.println("Let's inspect the AppProperties class : " + appProperties.toString());  
  };  
  }  
}

From our log :

AppProperties(email=contact@chrouki.com, name=demo, 
contacts=[contact@chrouki.com, admin@chrouki.com],
author=Author(name=Tarik, description=Developer),
site={host=chrouki.com, ip=127.0.0.1, port=8080}, 
sites={
   "first"=Site(host=chrouki.com, ip=127.0.0.1, port=8080),
   "second"=Site(host=another.chrouki.com, ip=127.0.0.1, port=9090) })

Download Source Code

The full code is available over on Github.

References