0%

Spring-Boot-Property

阅读更多

1 Overview

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

Spring Boot使用一个非常特殊的PropertySource顺序,旨在允许合理地覆盖属性值。具体的顺序如下(优先级从上到下降低)

  1. 在主目录上配置全局属性值(当devtools处于活动状态时,~/.spring-boot-devtools.properties
  2. 测试中的@TestPropertySource注解
  3. 测试中的属性。可在@SpringBootTest上使用,以及用于测试应用程序特定片段的测试注解
  4. 命令行参数
  5. SPRING_APPLICATION_JSON中的属性(嵌入在环境变量或系统属性中的内联JSON)
  6. ServletConfig初始化参数
  7. ServletContext初始化参数
  8. 来自java:comp/envJNDI属性
  9. Java系统变量(System.getProperties()
  10. 操作系统环境变量
  11. 来自random.*的随机变量
  12. 二方/三方jar包中的属性配置文件(application-{profile}.propertiesYAML
  13. 应用jar包中的属性配置文件(application-{profile}.propertiesYAML
  14. 二方/三方jar包中的属性配置文件(application.propertiesYAML
  15. 应用jar包中的属性配置文件(application.propertiesYAML
  16. @PropertySource注解
  17. 默认属性(SpringApplication.setDefaultProperties

2 Spring-Boot启动时加载Property的位置

SpringApplication.run方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    try {
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(
          args);

/* ====== 此处进行属性值的加载 ====== */
      ConfigurableEnvironment environment = prepareEnvironment(listeners,
          applicationArguments);
      configureIgnoreBeanInfo(environment);
      Banner printedBanner = printBanner(environment);
      context = createApplicationContext();
      exceptionReporters = getSpringFactoriesInstances(
          SpringBootExceptionReporter.class,
          new Class[] { ConfigurableApplicationContext.class }, context);
      prepareContext(context, environment, listeners, applicationArguments,
          printedBanner);
      refreshContext(context);
      afterRefresh(context, applicationArguments);
      stopWatch.stop();
      if (this.logStartupInfo) {
        new StartupInfoLogger(this.mainApplicationClass)
            .logStarted(getApplicationLog(), stopWatch);
      }
      listeners.started(context);
      callRunners(context, applicationArguments);
    }
    catch (Throwable ex) {
      handleRunFailure(context, ex, exceptionReporters, listeners);
      throw new IllegalStateException(ex);
    }

    try {
      listeners.running(context);
    }
    catch (Throwable ex) {
      handleRunFailure(context, ex, exceptionReporters, null);
      throw new IllegalStateException(ex);
    }
    return context;
  }

Spring默认包含几个EnvironmentPostProcessor

  1. SystemEnvironmentPropertySourceEnvironmentPostProcessor
  2. SpringApplicationJsonEnvironmentPostProcessor
  3. CloudFoundryVcapEnvironmentPostProcessor
  4. ConfigFileApplicationListener: 负责application.properties配置文件的解析和加载工作

3 @ConfigurationProperties

限制

  1. 注入的字段,必须包含set方法

生成spring-configuration-metadata.json文件,让IDEA可以解析到该自定义的配置项:增加如下依赖项,该processor会根据@ConfigurationProperties注解的内容,在编译时创建META-INF/spring-configuration-metadata.json文件

1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

4 命令行传入属性值

1
2
3
4
5
6
7
# --${key}=${value} 要加到最后
java -jar your-app.jar --server.port=8081

# -D${key}=${value} 要加到app.jar之前
java -jar -Dserver.port=8081 your-app.jar

mvn spring-boot:run -Drun.arguments="--server.port=8081"

5 参考