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.

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.

  1. A /config subdirectory of the current directory.
  2. The current directory.
  3. A classpath /config package.
  4. 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.

  1. With a nested “cache” property

    • app.cache.ttl is automatically converted to a Long
    • app.cache.max-entries is automatically converted to a Integer
  2. 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

上一篇: Spring Boot Managing Profiles with @Profile Annotation Example
下一篇: Spring Boot Passing Command Line Arguments Example
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号