Spring Boot – @ConfigurationProperties Annotation Example
Spring Boot allows you to externalize your configuration so you can work with the same application code in different environments. You can use properties files, YAML files, environment variables and command-line arguments to externalize configuration. In the following tutorial we demonstrate how to use the @ConfigurationProperties
annotation to map your configuration properties to a type safe configuration class.
Maven Dependencies
We use Apache Maven to manage our project dependencies. Add the following dependency to your project.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.memorynotfound.springboot</groupId>
<artifactId>configuration-properties</artifactId>
<version>1.0.0-SNAPSHOT</version>
<url>https://memorynotfound.com</url>
<name>Spring Boot - ${project.artifactId}</name>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- jsr 303 bean validation -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Configuration Properties
SpringApplication
will load properties from application.properties
files in the following locations and add them to the Spring Environment
. The list is ordered by precedence.
- A
/config
subdirectory of the current directory. - The current directory.
- A classpath
/config
package. - The classpath root.
application.properties
In this example we use an application.properties
file located at the classpath root.
app.cache.ttl=86400
app.cache.max-entries=1000
app.cors.allowed-origins[0]=*
app.cors.allowed-methods[0]=GET
app.cors.allowed-methods[1]=PUT
app.cors.allowed-methods[2]=POST
app.cors.allowed-methods[3]=DELETE
app.cors.allowed-methods[4]=OPTIONS
app.cors.allowed-headers[0]=*
app.cors.allow-credentials=true
app.cors.max-age=3600
application.yml
In this example we use an application.yml
file located at the classpath root. This YAML file is the equivalent to the .properties
file above.
app:
cache:
ttl: 86400
max-entries: 1000
cors:
allowed-origins:
- "*"
allowed-methods:
- "GET"
- "PUT"
- "POST"
- "DELETE"
- "OPTIONS"
allowed-headers:
- "*"
allow-credentials: true
max-age: 3600
Type-safe configuration properties
Using the
@Value("${property.name}")
annotation to inject configuration properties can sometimes be cumbersome, especially if you are working with multiple properties or your data is hierarchical in nature. Spring Boot provides an alternative method of working with properties that allows strongly typed beans to govern and validate the configuration of your application.
Relaxed binding
Spring Boot automatically uses relaxed rules for binding
Environment
properties to@ConfigurationProperties
beans. Meaning, there doesn’t need to be an exact match between theEnvironment
property name and the bean property name. Imagine you have a bean property calledallowCredentials
you can use the following configuration in your properties.
allowCredentials
using standard camel case syntax.allow-credentials
using dashed notation.allow_credentials
using underscore notation.ALLOW_CREDENTIALS
using upper case format.
@ConfigurationProperties example
The following POJO defines the following properties.
With a nested “cache” property
app.cache.ttl
is automatically converted to aLong
app.cache.max-entries
is automatically converted to aInteger
With a nested “cors” property
app.cors.allowed-origins
is a list ofString
app.cors.allowed-methods
is an array ofString
app.cors.allowed-headers
is a list ofString
app.cors.allow-credentials
is aBoolean
app.cors.max-age
is aInteger
@ConfigurationProperties Validation
Spring Boot will attempt to validate @ConfigurationProperties
classes whenever they are annotated with Spring’s @Validated
annotation. You can use JSR 303 Bean Validation javax.validation
constraint annotations directly on your configuration classes. The only thing you need is to add a compliant JSR-303 implementation to your classpath. We added the org.hibernate:hibernate-validator
implementation to ours, as you can see in the pom.xml file above. When using nested properties, you’ll have to use the @Valid
annotation to trigger its validation. Please look at the following example.
package com.memorynotfound.springboot;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
@Validated
@Configuration
@ConfigurationProperties("app")
public class ApplicationProperties {
@Valid
@NotNull
private Cache cache;
@Valid
@NotNull
private Cors cors;
public static class Cache {
@Max(1000)
private Integer ttl;
@Max(3600)
private Long maxEntries;
// ... getters and setters
@Override
public String toString() {
return "Cache{" +
"ttl=" + ttl +
", maxEntries=" + maxEntries +
'}';
}
}
public static class Cors {
private List<String> allowedOrigins;
private String[] allowedMethods;
private List<String> allowedHeaders;
private Boolean allowCredentials;
private Integer maxAge;
// ... getters and setters
@Override
public String toString() {
return "Cors{" +
"allowedOrigins=" + allowedOrigins +
", allowedMethods=" + Arrays.toString(allowedMethods) +
", allowedHeaders=" + allowedHeaders +
", allowCredentials=" + allowCredentials +
", maxAge=" + maxAge +
'}';
}
}
// ... getters and setters
@Override
public String toString() {
return "ApplicationProperties{" +
"cache=" + cache +
", cors=" + cors +
'}';
}
}
Run Spring Boot Application
We test the previous @ConfigurationProperties
configuration using a simple spring boot application.
package com.memorynotfound.springboot;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.annotation.PostConstruct;
@SpringBootApplication
public class Application {
private static Logger logger = LoggerFactory.getLogger(Application.class);
@Autowired
private ApplicationProperties properties;
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
@PostConstruct
private void init(){
logger.info("Spring Boot - @ConfigurationProperties annotation example");
logger.info(properties.toString());
}
}
Console Output
The application prints the following output to the console.
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.3.RELEASE)
2017-05-29 15:50:19.499 INFO 13631 --- [ main] c.memorynotfound.springboot.Application : Spring Boot - @ConfigurationProperties example
2017-05-29 15:50:19.539 INFO 13631 --- [ main] c.memorynotfound.springboot.Application : ApplicationProperties{cache=Cache{ttl=86400, maxEntries=1000}, cors=Cors{allowedOrigins=[*], allowedMethods=[GET, PUT, POST, DELETE, OPTIONS], allowedHeaders=[*], allowCredentials=true, maxAge=3600}}
Console Output Bean Validation Failed
When using JSR 303 Bean Validation
you can use the javax.validation
annotations to validate the configuration properties. When the validation fails because of invalid configuration properties. Spring Boot wont’t start and give the following message.
***************************
APPLICATION FAILED TO START
***************************
Description:
Binding to target ApplicationProperties{cache=Cache{ttl=86400, maxEntries=1000}, cors=Cors{allowedOrigins=[*], allowedMethods=[GET, PUT, POST, DELETE, OPTIONS], allowedHeaders=[*], allowCredentials=true, maxAge=3600}} failed:
Property: app.cache.maxEntries
Value: 1000
Reason: must be less than or equal to 100
Property: app.cache.ttl
Value: 86400
Reason: must be less than or equal to 3600
References
- Spring Boot – @ConfigurationProperties Documentation
- Spring Boot – @ConfigurationProperties Validation Documentation
Where is the max value constraint being set?
Hello,
You can annotate any configuration properties using the javax.persistence api annotations.
I added the @Max(1000) to the ‘ttl’ property for testing purposes, but omitted it in the tutorial.
I’ll update the tutorial and add the annotation
Kr,
Memorynotfound
Got it, thanks!