专栏首页代码拾遗Spring Boot 2.0 教程 - 配置详解

Spring Boot 2.0 教程 - 配置详解

Spring Boot 可以通过properties文件,YAML文件,环境变量和命令行参数进行配置。属性值可以通过,@Value注解,Environment或者ConfigurationProperties注入到应用中。 配置的优先级如下:

  1. 如果使用了devtools,则以home目录下的~/.spring-boot-devtools.properties为主
  2. @TestPropertySource注解的测试
  3. @SpringBootTest#properties注解的测试
  4. 命令行参数
  5. SPRING_APPLICATION_JSON提供的属性(JSON格式,从环境变量或者系统属性中获取)
  6. ServletConfig配置的属性
  7. ServletContext配置的属性
  8. JNDI配置的属性,(java:comp/env)
  9. Java 系统属性,System.getProperties()
  10. 系统环境变量
  11. RandomValuePropertySource进针对于random.*
  12. jar包外部指定profile文件,例如application-{profile}.properties(YAML 同)
  13. jar包内部的指定profile文件
  14. 应用外部的application.properties
  15. 应用内部的application.properties
  16. @PropertySource注解
  17. 默认属性(SpringApplication.setDefaultProperties()) 例如:
import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*

@Component
public class MyBean {

    @Value("${name}")
    private String name;

    // ...

}

application.properties提供了name的默认值,当运行程序的时候可以通过提供命令行的值覆盖其默认值,java -jar app.jar --name="spring"

配置随机值

RandomValuePropertySource可以很方便的注入随机值到配置文件中。例如

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}
访问命令行参数

默认情况下,SpringApplication会将命令行参数转换为property并添加到Environment中。正如前面提到的,命令行参数会覆盖其他的配置。 如果不希望命令行参数添加到Environment中可以通过调用SpringApplication.setAddCommandLineProperties(fals)设置。

应用配置文件

SpringApplication加载application.properties文件,将其变量添加到Environment中,查找位置:

  1. 当前目录的/config目录
  2. 当前目录
  3. classpath下的config子目录
  4. classpath目录 如果不想使用application.properties文件可以使用spring.config.name指定配置名字,同样可以通过spring.config.location指定配置文件的位置
java -jar myproject.jar --spring.config.name=myproject
java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

如果spring.config.location使用的是目录,那么其应该以/结尾,运行的时候会将spring.confing.name的名字追加到后来查找配置文件。

指定配置文件

除了application.properties文件外,同样可以以application-{profile}.properties的形式命名指定配置文件。Environment有一个默认的配置,(default),即如果没有激活其他配置文件,默认使用application-default.properties。如果提供了多个指定配置文件,则选择最新的配置文件。

配置文件的占位符

application.properties中的定义的值可以在后续的配置中使用,例如

app.name=MyApp
app.description=${app.name} is a Spring Boot application
使用YAML配置文件

当添加了SnakeYAML时,SpringApplication即可支持YAML配置,添加spring-boot-starter 自动会添加对SnakeYAML的依赖。

加载YAML

SpringApplication有两种加载YAML配置文件的方式,1.使用YamlPropertiesFactoryBean将YAML加载为Properties,2. 使用YamlMapFactoryBean将YAML加载为map。 以下YAML配置文件:

environments:
    dev:
        url: http://dev.example.com
        name: Developer Setup
    prod:
        url: http://another.example.com
        name: My Cool App

上面的配置文件等同的properties配置

environments.dev.url=http://dev.example.com
environments.dev.name=Developer Setup
environments.prod.url=http://another.example.com
environments.prod.name=My Cool App

YAML列表默认会添加序号(index)例如:

my:
servers:
    - dev.example.com
    - another.example.com

等同的properties配置为

my.servers[0]=dev.example.com
my.servers[1]=another.example.com

可以通过@ConfigurationProperties注解将属性绑定到变量中,例如:

@ConfigurationProperties(prefix="my")
public class Config {

    private List<String> servers = new ArrayList<String>();

    public List<String> getServers() {
        return this.servers;
    }
}
多个YAML配置文件

可以在单个文件中使用spring.profiles作为key指定多个YAML配置文件。例如:

server:
    address: 192.168.1.100
---
spring:
    profiles: development
server:
    address: 127.0.0.1
---
spring:
    profiles: production
server:
    address: 192.168.1.120

按照上述文件表示,如果development配置激活了,则server.address设置为127.0.0.1。同样的,如果production配置激活则server.address配置为192.168.1.120。如果development和production都没有启用,则使用默认即server.address设置为192.168.1.100 如果没有指定激活哪个配置,那么默认使用default的配置,例如以下示例,spring.security.user.password只有在都不指定激活配置的时候才会使用

server:
  port: 8000
---
spring:
  profiles: default
  security:
    user:
      password: weak

下面的例子密码都会被设置,因为他不属于任何一个配置:

server:
  port: 8000
spring:
  security:
    user:
      password: weak
使用@ConfigurationProperties注入值

从多个properties注入值的时候使用@Value()非常的麻烦,Spring Boot可以使用@ConfigurationProperties进行简化配置,例如:

package com.example;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("acme")
public class AcmeProperties {

    private boolean enabled;

    private InetAddress remoteAddress;

    private final Security security = new Security();

    public boolean isEnabled() { ... }

    public void setEnabled(boolean enabled) { ... }

    public InetAddress getRemoteAddress() { ... }

    public void setRemoteAddress(InetAddress remoteAddress) { ... }

    public Security getSecurity() { ... }

    public static class Security {

        private String username;

        private String password;

        private List<String> roles = new ArrayList<>(Collections.singleton("USER"));

        public String getUsername() { ... }

        public void setUsername(String username) { ... }

        public String getPassword() { ... }

        public void setPassword(String password) { ... }

        public List<String> getRoles() { ... }

        public void setRoles(List<String> roles) { ... }

    }
}

其属性定义如下

acme.enable=false
acme.remote-address=192.168.1.1
acme.security.username=username
acme.security.password=password
acme.security.roles=roles1,roles2

需要在@Configuration的配置中起用

@Configuration
@EnableConfigurationProperties(AcmeProperties.class)
public class MyConfiguration {
}

当然如果AcmeProperties类是一个bean则无需配置指定@EnableConfigurationProperties(AcmeProperties.class)例如:

@Component
@ConfigurationProperties(prefix="acme")
public class AcmeProperties {

    // ... see the preceding example

}

等同的YAML配置文件

acme:
    remote-address: 192.168.1.1
    security:
        username: admin
        roles:
          - USER
          - ADMIN
松绑定规则

通过@ConfigurationProperties绑定变量非常的灵活,例如:

@ConfigurationProperties(prefix="acme.my-project.person")
public class OwnerProperties {

    private String firstName;

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

}

对于下列的方式都可以成功绑定

  • acme.my-porject.person.first-name
  • acme.my-project.person.first_name
  • acme.my-project.person.firstName
  • ACME_MYPROJECT_PERSON_FIRSTNAME
@ConfigurationProperties 校验

@ConfigurationProperties 支持JSR-303 javax.validation注解进行校验,例如

@ConfigurationProperties(prefix="acme")
@Validated
public class AcmeProperties {

    @NotNull
    private InetAddress remoteAddress;

    // ... getters and setters

}
@ConfigurationProperties和@Value的区别

功能

@configurationProperties

@Value

松绑定规则

Y

N

元数据支持

Y

N

SPEL

N

Y

Profiles

Spring Profile可以将应用的配置分成多部分,只有在指定的环境下生效。任何@component或者@Configutaion都可以使用@Profile限制其加载,例如

@Configuration
@Profile("production")
public class ProductionConfiguration {

    // ...

}

可以使用spring.profiles.activeEnvironment变量设置激活哪个profile。例如在application.properties中设置

spring.profiles.active=dev,hsqldb

或者使用命令行

java -jar app.jar --spring.profiles.active=dev,hsqldb

本文分享自微信公众号 - 代码拾遗(gh_8f61e8bcb1b1)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-05-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SpringMVC 教程 - Controller

    Controller也是一个标准的Spring bean,可以在Servlet的WebApplicationContext中定义。也可以使用@Controlle...

    代码拾遗
  • ​SpringMVC 教程 - Handler Method

    由注解@RequestMapping注解修饰的处理请求的函数的签名非常的灵活,可以使用controller函数支持的一系列参数和返回值。

    代码拾遗
  • SpringMVC 教程 - Filter

    浏览器只能通过GET或者POST提交FORM数据,但是非浏览器的客户端可以使用PUT或者PATCH。Servlet API仅为POST方法提供了ServletR...

    代码拾遗
  • SpringBoot使用及原理浅尝

    最近微服务很热,而SpringBoot以轻量级和内嵌tomcat,方便启动调试为微服务越来越被采用,而现在前沿的技术的demo一般都也使用SpringBoot编...

    加多
  • commons-configuration2:properties文件写入中文(no escape)

    properties 是java标准支持的配置文件格式,默认编码ISO 8859-1,unicode字符会被转义(Unicode escapes) 参见 ht...

    用户1148648
  • 为什么美容院需要一款美业小程序?

    美业的客户画像和消费场景十分清晰,我们也习惯了整个流程,到店,消费,离开,就这几个步骤,或是再有个提前预约,办个卡,美业特性之一是客户群体基本上都来自店铺周边,...

    微盛企微管家
  • Python那些事——你不知道的python的“独门暗器”!

    随着近几年人工智能的流行,从而引发了一个编程语言的兴起,我想说到这,大家应该都明白了这是什么吧,没错它就是大名鼎鼎的——Python

    燕大侠V
  • RabbitMQ基础教程之基本使用篇

    一灰灰blog
  • Django-10 博客帖子增删改查功能

    今天学习如何使用基于类的视图来创建,更新和删除帖子。一旦我们习惯使用这种方式会非常方便。 接下来开始:

    亚乐记
  • 这些JavaDoc中的注释你都知道了吗?

    行注释和段注释大多数都不陌生,而说明注释了解的可能少一点,因为它支持有很多标签,说明注释允许在程序中嵌入相关程序信息并使用HTML标签。

    beifengtz

扫码关注云+社区

领取腾讯云代金券