Skip to content

24.Application 属性文件

1. 加载顺序

按以下优先级顺序(从高到低)加载 application.properties文件:

  1. A /config subdirectory of the current directory
  2. The current directory
  3. A classpath /config package
  4. The classpath root

可通过定义环境变量级别的(操作系统环境变量、系统属性、命令行参数) spring.config.additional-location添加额外的配置文件路径,并拥有最高优先级。

例:

$ java -jar myproject.jar --spring.config.name=myproject --spring.config.additional-location=classpath:/custom-config/,file:./custom-config/

那么加载优先级就是:

  1. file:./custom-config/
  2. classpath:custom-config/
  3. file:./config/
  4. file:./
  5. classpath:/config/
  6. classpath:/

操作系统级别的环境变量需要改写为大写字母+下划线的组成格式(for example, SPRING_CONFIG_NAME instead of spring.config.name)。

2. Profile-specific 属性

此类文件的命名格式为application-{profile}.properties

Application 环境中有一系列的默认配置文件,所以如果没有激活特别的配置文件,那么使用默认的。

profile-specificapplication.properties一起加载,并且无论在jar包里面或外面都会覆盖掉 application.properties的属性。

注意:如果使用了 spring.config.location指定了任何文件,那么该配置文件的变种会失效,所以可以使用文件夹的形式防止。

3. 属性占位符

在环境中定义了属性之后,可以在application.properties 中使用:

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

4. YAML

SnakeYAML在classpath中就可以使用YAML代替properties做配置。

If you use “Starters”, SnakeYAML is automatically provided by spring-boot-starter.

缺点

  • 不能通过@PropertySource载入配置文件。

  • 配置文件否定和配置文件表达式将不会按预期运行。

5. 类型安全的配置属性

将一堆属性配置注入到属性类上面。

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

    属性...

    getter setter function

}

acme就是在配置文件中的属性。

以下中情况不需要属性的setter方法:

  • map
  • 嵌套的POJO类型的属性已经被初始化了。如果您希望绑定器使用其默认构造函数动态创建实例,则需要一个setter。

5.1 第三方配置

@ConfigurationProperties可以用在类和public @Bean 方法上面。

@ConfigurationProperties(prefix = "another")
@Bean
public AnotherComponent anotherComponent() {
    ...
}

5.2 宽松的绑定规则

Spring Boot将Environment属性绑定到@ConfigurationProperties beans时会使用一些宽松的规则,所以Environment属性名和bean属性名不需要精确匹配。

四种格式的应用范围:

Property Note
acme.my-project.person.first-name Kebab case, which is recommended for use in .properties and .yml files.
acme.myProject.person.firstName Standard camel case syntax.
acme.my_project.person.first_name Underscore notation, which is an alternative format for use in .properties and .yml files.
ACME_MYPROJECT_PERSON_FIRSTNAME Upper case format, which is recommended when using system environment variables.

注意prefix的值必须是虚线分隔格式。

四种属性定义方式的可用属性命名规范:

Property Source Simple List
Properties Files Camel case, kebab case, or underscore notation Standard list syntax using [ ] or comma-separated values
YAML Files Camel case, kebab case, or underscore notation Standard YAML list syntax or comma-separated values
Environment Variables Upper case format with underscore as the delimiter. _ should not be used within a property name Numeric values surrounded by underscores, such as MY_ACME_1_OTHER = my.acme[1].other
System properties Camel case, kebab case, or underscore notation Standard list syntax using [ ] or comma-separated values

当绑定 Map属性时,如果key中有字符的范围不在:小写字母数字、-,就要使用[]包围。

acme:
  map:
    "[/key1]": value1

否则这些超范围字符会被去除。

5.3 合并复杂类型

对于list类型来说,只会使用多个配置源中的一个。

对于map类型来说,会合并多个配置源。

例:

acme:
  map:
    key1:
      name: my name 1
      description: my description 1
---
spring:
  profiles: dev
acme:
  map:
    key1:
      name: dev name 1
    key2:
      name: dev name 2
      description: dev description 2

若激活了dev,key1的值为:name: dev name 1;description: my description 1。

5.4 @ConfigurationProperties 验证

Spring Boot会验证添加了Spring@Validated注解的@ConfigurationProperties 类。然后就可以使用JSR-303 javax.validation的注解。

@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

    }
    // ... getters and setters

}

嵌套属性最好加上@Valid注解。

你也可以通过创建一个叫做configurationPropertiesValidator的bean来添加自定义的Spring Validator@Bean方法需要声明为static示例