zoukankan      html  css  js  c++  java
  • SpringBoot 教程之属性加载详解

    目录

    加载 property 顺序

    Spring Boot 加载 property 顺序如下:

    1. Devtools 全局配置 (当 devtools 被激活 ~/.spring-boot-devtools.properties).
    2. 测试环境中的 @TestPropertySource 注解配置
    3. 测试环境中的属性 properties@SpringBootTest 和 测试注解.
    4. 命令行参数
    5. SPRING_APPLICATION_JSON 属性
    6. ServletConfig 初始化参数
    7. ServletContext 初始化参数
    8. JNDI attributes from 通过 java:comp/env 配置的 JNDI 属性
    9. Java 系统属性 (System.getProperties())
    10. 操作系统环境比那里
    11. RandomValuePropertySource 加载 random.* 形式的属性
    12. jar 包外的 application-{profile}.properties 或 application-{profile}.yml 配置
    13. jar 包内的 application-{profile}.properties 或 application-{profile}.yml 配置
    14. jar 包外的 application.properties 或 application.yml 配置
    15. jar 包内的 application.properties 或 application.yml 配置
    16. @PropertySource 绑定的配置
    17. 默认属性 (通过 SpringApplication.setDefaultProperties 指定)

    随机属性

    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 会获取 -- 参数(例如 --server.port=9000 ),并将这个 property 添加到 Spring 的 Environment 中。

    如果不想加载命令行属性,可以通过 SpringApplication.setAddCommandLineProperties(false) 禁用。

    Application 属性文件

    SpringApplication 会自动加载以下路径下的 application.properties 配置文件,将其中的属性读到 Spring 的 Environment 中。

    1. 当前目录的 /config 子目录
    2. 当前目录
    3. classpath 路径下的 /config package
    4. classpath 根路径

    注:

    以上列表的配置文件会根据顺序,后序的配置会覆盖前序的配置。

    你可以选择 YAML(yml) 配置文件替换 properties 配置文件。

    如果不喜欢 application.properties 作为配置文件名,可以使用 spring.config.name 环境变量替换:

    $ java -jar myproject.jar --spring.config.name=myproject

    可以使用 spring.config.location 环境变量指定配置文件路径:

    $ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

    Profile 特定属性

    如果定义 application-{profile}.properties 形式的配置文件,将被视为 profile 环境下的特定配置。

    可以通过 spring.profiles.active 参数来激活 profile,如果没有激活的 profile,默认会加载 application-default.properties 中的配置。

    属性中的占位符

    application.properties 中的值会被 Environment 过滤,所以,可以引用之前定义的属性。

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

    注:你可以使用此技术来创建 Spring Boot 属性变量。请参考: Section 77.4, “Use ‘Short’ Command Line Arguments

    YAML 属性

    Spring Framework provides two convenient classes that can be used to load YAML documents. The YamlPropertiesFactoryBean loads YAML as Properties and the YamlMapFactoryBean loads YAML as a Map.

    Spring 框架有两个类支持加载 YAML 文件。

    • YamlPropertiesFactoryBean 将 YAML 文件的配置加载为 Properties 。
    • YamlMapFactoryBean 将 YAML 文件的配置加载为 Map 。

    示例 1

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

    等价于:

    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 支持列表形式,等价于 property 中的 [index] :

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

    等价于

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

    访问属性

    YamlPropertySourceLoader 类会将 YAML 配置转化为 Spring Environment 类中的 PropertySource 。然后,你可以如同 properties 文件中的属性一样,使用 @Value 注解来访问 YAML 中配置的属性。

    多 profile 配置

    server:
      address: 192.168.1.100
    ---
    spring:
      profiles: development
    server:
      address: 127.0.0.1
    ---
    spring:
      profiles: production & eu-central
    server:
      address: 192.168.1.120

    YAML 的缺点

    注:YAML 注解中的属性不能通过 @PropertySource 注解来访问。所以,如果你的项目中使用了一些自定义属性文件,建议不要用 YAML。

    属性前缀

    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(prefix="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.enabled
    • acme.remote-address
    • acme.security.username
    • acme.security.password
    • acme.security.roles

    然后,你需要使用 @EnableConfigurationProperties 注解将属性类注入配置类中。

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

    属性松散绑定规则

    Spring Boot 属性名绑定比较松散。

    以下属性 key 都是等价的:

    PropertyNote
    acme.my-project.person.first-name - 分隔
    acme.myProject.person.firstName 驼峰命名
    acme.my_project.person.first_name _ 分隔
    ACME_MYPROJECT_PERSON_FIRSTNAME 大写字母

    属性转换

    如果需要类型转换,你可以提供一个 ConversionService bean (一个名叫 conversionService 的 bean) 或自定义属性配置 (一个 CustomEditorConfigurer bean) 或自定义的 Converters (被 @ConfigurationPropertiesBinding 注解修饰的 bena)。

    时间单位转换

    Spring 使用 java.time.Duration 类代表时间大小,以下场景适用:

    • 除非指定 @DurationUnit ,否则一个 long 代表的时间为毫秒。
    • ISO-8601 标准格式( java.time.Duration 的实现就是参照此标准)
    • 你也可以使用以下支持的单位:
      • ns - 纳秒
      • us - 微秒
      • ms - 毫秒
      • s - 秒
      • m - 分
      • h - 时
      • d - 天

    示例:

    @ConfigurationProperties("app.system")
    public class AppSystemProperties {
    
        @DurationUnit(ChronoUnit.SECONDS)
        private Duration sessionTimeout = Duration.ofSeconds(30);
    
        private Duration readTimeout = Duration.ofMillis(1000);
    
        public Duration getSessionTimeout() {
            return this.sessionTimeout;
        }
    
        public void setSessionTimeout(Duration sessionTimeout) {
            this.sessionTimeout = sessionTimeout;
        }
    
        public Duration getReadTimeout() {
            return this.readTimeout;
        }
    
        public void setReadTimeout(Duration readTimeout) {
            this.readTimeout = readTimeout;
        }
    
    }

    数据大小转换

    Spring 使用 DataSize 类代表数据大小,以下场景适用:

    • long 值(默认视为 byte)
    • 你也可以使用以下支持的单位:
      • B
      • KB
      • MB
      • GB
      • TB

    示例:

    @ConfigurationProperties("app.io")
    public class AppIoProperties {
    
        @DataSizeUnit(DataUnit.MEGABYTES)
        private DataSize bufferSize = DataSize.ofMegabytes(2);
    
        private DataSize sizeThreshold = DataSize.ofBytes(512);
    
        public DataSize getBufferSize() {
            return this.bufferSize;
        }
    
        public void setBufferSize(DataSize bufferSize) {
            this.bufferSize = bufferSize;
        }
    
        public DataSize getSizeThreshold() {
            return this.sizeThreshold;
        }
    
        public void setSizeThreshold(DataSize sizeThreshold) {
            this.sizeThreshold = sizeThreshold;
        }
    
    }

    校验属性

    @ConfigurationProperties(prefix="acme")
    @Validated
    public class AcmeProperties {
    
        @NotNull
        private InetAddress remoteAddress;
    
        @Valid
        private final Security security = new Security();
    
        // ... getters and setters
    
        public static class Security {
    
            @NotEmpty
            public String username;
    
            // ... getters and setters
    
        }
    
    }

    你也可以自定义一个名为 configurationPropertiesValidator 的校验器 Bean。获取这个 @Bean 的方法必须声明为 static

    示例源码

    示例源码:spring-boot-property

    参考资料

  • 相关阅读:
    第二阶段冲刺站立会议报告
    09软件工程读后感之三
    08软件工程读后感之二
    07软件工程读后感之一
    一个整数数组中最大字数组二
    返回一个二维数组最大联通子数组的和
    项目阶段总结
    大道至简阅读笔记之三
    大道至简阅读笔记二
    课堂设计
  • 原文地址:https://www.cnblogs.com/aimei/p/12201479.html
Copyright © 2011-2022 走看看