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 the Environment property name and the bean property name. Imagine you have a bean property called allowCredentials 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 a Long
- app.cache.max-entries is automatically converted to a Integer
With a nested “cors” property
- app.cors.allowed-origins is a list of String
- app.cors.allowed-methods is an array of String
- app.cors.allowed-headers is a list of String
- app.cors.allow-credentials is a Boolean
- app.cors.max-age is a Integer
@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
Download
From:一号门
COMMENTS