美文网首页Spring-Boot程序员我爱编程
[翻译]Spring Boot 特征参考2——外部配置:上

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

作者: 飞来来 | 来源:发表于2017-09-03 12:37 被阅读245次

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

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

    目录

    • 1 外部配置
      • 1.1 配置随机值
      • 1.2 访问命令行属性
      • 1.3 应用程式属性档案
      • 1.4 配置文件特定的属性
      • 1.5 properties中的占位符
      • 1.6 使用YAML而不是properties
        • 1.6.1 加载YAML
        • 1.6.2 将YAML作为Spring环境中的属性
        • 1.6.3 多个YAML文件
        • 1.6.4 YAML的缺点
        • 1.6.5 合并YAML列表

    1. 外部配置

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

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

      1. Devtools全局设置属性在您的主目录(~/.spring-boot-devtools.properties当devtools是活动的)。
      1. @TestPropertySource注释在你的单元测试中。
      1. @SpringBootTest #properties 注解属性在你的单元测试中。
      1. 命令行参数。
      1. 来自SPRING_APPLICATION_JSON的属性(嵌入在环境变量或系统属性中的内嵌JSON)
      1. *ServletConfig *init参数。
      1. *ServletContext *init参数。
      1. 来自java的JNDI属性:java:comp/env
      1. Java系统属性(System.getProperties())。
      1. OS环境变量。
      1. 一个RandomValuePropertySource,只有随机的属性。
      1. 特定于应用程序的应用程序属性在打包的jar之外(application- {profile} .properties和YAML变量)。
      1. 封装在jar中的配置文件特定的应用程序属性(application- {profile} .properties和YAML变量)。
      1. 您的打包的jar(application.properties和YAML变量)之外的应用程序属性。
      1. 应用程序属性打包在你的jar中 (application.properties和YAML变量)。
      1. @PropertySource注释在您的@Configuration类。
      1. 默认属性(使用SpringApplication.setDefaultProperties指定)。

    要提供一个具体的例子,假设你开发一个使用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

      1. 一个/ config子目录中。
      1. 当前目录
      1. 一个 classpath /config 保中
      1. 类路径根

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

    注意:您也可以使用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)。

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

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/wfwdjxtx.html