Spring-Boot程序员我爱编程

[翻译]Spring Boot 特征参考2——外部配置:上

2017-09-03  本文已影响245人  飞来来

本文翻译自:http://docs.spring.io/spring-boot/docs/2.0.0.M2/reference/htmlsingle/

详细介绍Spring boot的关键特征,针对有一定springboot基础的同学。

目录

1. 外部配置

Spring Boot允许您外部化配置,以便在不同的环境中使用相同的应用程序代码。您可以使用属性文件,YAML文件,环境变量和命令行参数来外部化配置。可以使用@Value注释将属性值直接注入到您的bean中,通过Spring的Environment抽象访问或通过@ConfigurationProperties绑定到结构化对象。

Spring Boot使用非常特殊的PropertySource命令,旨在允许明智地覆盖值。属性按以下顺序考虑:

要提供一个具体的例子,假设你开发一个使用name属性的@Component

import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*

@Component
public class MyBean {

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

    // ...

}

在您的应用程序类路径(例如,您的jar中)中,您可以拥有一个application.properties,它为name提供了明智的默认属性值。在新的环境中运行时,可以在您的jar之外提供一个application.properties来覆盖该name;对于一次性测试,您可以使用特定的命令行开关启动(例如,java -jar app.jar --name =“Spring”)。

注意:
SPRING_APPLICATION_JSON属性可以在命令行中提供一个环境变量。例如在UN * X shell中:

$ SPRING_APPLICATION_JSON ='{“foo”:{“bar”:“spam”}}'java -jar myapp.jar

在这个例子中,你将在springEnvironment中以foo.bar=spam结尾。您还可以在系统变量中将JSON作为spring.application.json提供:

$ java -Dspring.application.json ='{“foo”:“bar”}'-jar myapp.jar

或命令行参数:

$ java - jar myapp.jar --spring.application.json ='{“foo”:“bar”}'

或作为JNDI变量java:comp / env / spring.application.json

1.1 配置随机值

RandomValuePropertySource可用于注入随机值(例如,进入秘密或测试用例)。它可以产生整数,长整数,uuid或字符串,例如:

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]}

random.int* 语法是*OPEN value (,max) CLOSE
*,其中OPEN,CLOSE是任何字符和值,max是整数。如果提供max,则值为最小值,max为最大值(仅包含)。

1.2 访问命令行属性

默认情况下,SpringApplication将任何命令行选项参数(以' - '开头,例如--server.port = 9000)转换为property,并将其添加到Spring的Environment中。

如上所述,命令行属性始终优先于其他属性源。如果不希望将命令行属性添加到Environment中,可以使用SpringApplication.setAddCommandLineProperties(false)禁用它们。

1.3 应用程式属性档案

SpringApplication将从以下位置的application.properties文件中加载属性,并将它们添加到当前目录的Spring Environment

列表按优先级排序(在列表中定义的属性中定义的属性将覆盖在较低位置中定义的位置)。

注意:您也可以使用YAML('.yml')文件替代“.properties”。

如果您不喜欢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.namespring.config.location非常早地用于确定哪些文件必须被加载,因此必须将其定义为环境属性(通常是OS env,system属性或命令行参数)。

如果spring.config.location包含目录(而不是文件),它们应该以/结束(并将在加载之前附加从spring.config.name生成的名称,包括特定于文件的文件名)。在spring.config.location中指定的文件按原样使用,没有支持特定于配置文件的变量,并且将被任何特定于配置文件的属性覆盖。

默认的搜索路径classpath:,classpath:/ config,file:,file:config /始终被使用,不管spring.config.location的值如何。 此搜索路径从最低优先级排序(file:config / 最高优先级)。

如果您指定自己的位置,则它们优先于所有默认位置,并使用相同的最低到最高优先级排序。 这样,您可以在application.properties(或使用spring.config.name选择的其他基础名称)中为应用程序设置默认值,并在运行时使用不同的文件覆盖它,并保留默认值。

注意:如果使用环境变量而不是系统属性,则大多数操作系统不允许使用周期分隔的键名称,但可以使用下划线(例如SPRING_CONFIG_NAME,而不是spring.config.name)。

注意:如果你在一个容器中运行JNDI属性(在java:comp / env)或者servlet 可以使用上下文初始化参数来代替环境变量或系统属性。

1.4 配置文件特定的属性

除了application.properties文件之外,还可以使用命名约定application- {profile} .properties定义特定于配置文件的属性。Environment具有默认配置文件(默认为[default]),如果没有设置活动配置文件(即,如果没有显式激活配置文件,则加载了来自application-default.properties的属性)。

配置文件特定的属性从与标准application.properties相同的位置加载,配置文件特定的文件始终覆盖非特定的文件,而不管特定于配置文件的文件是否在打包的jar内部或外部。

如果指定了几个配置文件,则应用最后一个优先策略。例如,由spring.profiles.active属性指定的配置文件通过SpringApplication API配置后添加,因此优先。

注意:如果您在spring.config.location中指定了任何文件,则不会考虑这些文件的特定于配置文件的变量。使用 如果还要使用特定于配置文件的属性,请在spring.config.location中指定目录。

1.5 properties中的占位符

application.properties中的值通过使用现有Environment进行过滤,以便您可以参考以前定义的值(例如,从系统属性)。

app.name = MyApp 
app.description = $ {app.name} is a Spring Boot application

您还可以使用此技术创建现有Spring Boot属性的“简短”变体。

1.6 使用YAML而不是properties

YAML是JSON的超集,因此这是一种用于指定分层配置数据的非常方便的格式。只要您的类路径中有SnakeYAML库,SpringApplication类将自动支持YAML作为属性的替代方法。

注意:如果您使用“Starters”,SnakeYAML将通过spring-boot-starter自动提供。

1.6.1 加载YAML

Spring Framework提供了两个可用于加载YAML文档的方便类。 YamlPropertiesFactoryBean将加载YAML作为Properties,并且YamlMapFactoryBean将加载YAML作为Map。例如,以下YAML文档:

environments:
    dev:
        url: http://dev.bar.com
        name: Developer Setup
    prod:
        url: http://foo.bar.com
        name: My Cool App

将被转换成这些属性:

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

YAML列表表示为具有[index]取消引用的属性键,例如YAML:

my:
   servers:
       - dev.bar.com
       - foo.bar.com

将被转换成这些属性:

my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com

要使用Spring DataBinder实用程序(这是@ConfigurationProperties所做的)绑定到这样的属性,您需要在类型为java.util.List(或Set)的目标bean中具有一个属性,并且您需要提供一个setter,或者用可变值初始化它,例如这将绑定到上面的属性

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

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

    public List<String> getServers() {
        return this.servers;
    }
}

注意:

配置列表时,需要特别小心,因为覆盖方式将无法正常工作。在上面的例子中,当我的几个地方重新定义my.servers时,单个元素的目标是覆盖,而不是列表。要确保具有较高优先级的PropertySource可以覆盖列表,您需要将其定义为单个属性:

my:
   servers: dev.bar.com,foo.bar.com
1.6.2 将YAML作为Spring环境中的属性

可以使用YamlPropertySourceLoader类在SpringEnvironment中将YAML作为PropertySource进行公开。这允许您使用熟悉的@Value注释和占位符语法来访问YAML属性。

1.6.3 多个YAML文件

您可以使用spring.profiles键指定单个文件中的多个配置文件特定的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。如果developmentproduction配置文件未启用,则该属性的值将为192.168.1.100。

如果应用程序上下文启动时没有显式激活,默认配置文件将被激活。所以在这个YAML中,我们为security.user.password设置一个仅在“默认”配置文件中可用的值:

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

而在此示例中,由于密码未附加到任何配置文件,因此始终设置密码,必要时必须在所有其他配置文件中显式重置密码:

server:
  port: 8000
security:
  user:
    password: weak

使用“spring.profiles”元素指定的弹簧轮廓可以选择使用!字符。如果为单个文档指定了否定和非否定的配置文件,则至少有一个非否定配置文件必须匹配,没有否定配置文件可能匹配。

1.6.4 YAML的缺点

不能通过@PropertySource注释来加载YAML文件。因此,在需要以这种方式加载值的情况下,需要使用属性文件。

1.6.5 合并YAML列表

如上所述,任何YAML内容最终都转化为属性。当通过配置文件覆盖“列表”属性时,该过程可能是直观的。

例如,假设默认情况下,namedescription属性为nullMyPojo对象。让我们从FooProperties中公开MyPojo的列表:

@ConfigurationProperties("foo")
public class FooProperties {

    private final List<MyPojo> list = new ArrayList<>();

    public List<MyPojo> getList() {
        return this.list;
    }

}

请考虑以下配置:

foo:
  list:
    - name: my name
      description: my description
---
spring:
  profiles: dev
foo:
  list:
    - name: my another name

如果dev配置文件不活动,FooProperties.list将包含一个如上定义的MyPojo条目。如果启用了dev配置文件,list仍将只包含一个条目(名称为“我的另一个名称”,描述为null)。此配置不会将第二个MyPojo实例添加到列表中,它不会合并项。

foo:
  list:
    - name: my name
      description: my description
    - name: another name
      description: another description
---
spring:
  profiles: dev
foo:
  list:
     - name: my another name

在上面的示例中,考虑到dev配置文件处于活动状态,FooProperties.list将包含一个MyPojo实体(包含名称为“my another 描述为null)。

当在多个配置文件中指定集合时,将使用具有最高优先级的集合(并且仅使用该集合):

上一篇下一篇

猜你喜欢

热点阅读