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=demoThe 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:
@ConfigurationPropertiessupports both.propertiesand.ymlfile.
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=demoNested 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=9090equivalent 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: 9090Demo
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.