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.