24. Externalized Configuration

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

Spring Boot使用了一个非常特殊的PropertySource顺序,该顺序被设计为允许合理地覆盖值.属性的顺序如下:

  1. 位于用户目录的Devtools global属性配置 (当devtools激活时文件为:~/.spring-boot-devtools.properties)
  2. 测试类上标注@TestPropertySource属性值.
  3. 测试类上标注@SpringBootTest注解的properties值.
  4. 命令行参数.
  5. SPRING_APPLICATION_JSON定义的属性值(环境变量或系统属性的内置JSOM).
  6. ServletConfig配置的初始参数.
  7. ServletContext配置的初始参数.
  8. java:comp/env定义的JNDI属性.
  9. Java系统属性(System.getProperties()).
  10. 系统环境变量.
  11. random.*属性开头的RandomValuePropertySource
  12. 依赖jar包的Profile-specific应用属性(application-{profile}.properties和YAML变量).
  13. 当前应用jar包的Profile-specific应用属性(application-{profile}.properties和YAML变量).
  14. 依赖jar包应用属性(application.properties和YAML变量).
  15. 当前应用jar包的应用属性(application.properties和YAML变量).
  16. @Configuration配置类上标注@ProperSource注解值.
  17. 默认属性(由SpringApplication.setDefaultProperties配置).

为了提供一个具体的例子,假设你正在开发一个@Component类,使用一个名为name的属性,如以下示例所示:

  1. import org.springframework.stereotype.*;
  2. import org.springframework.beans.factory.annotation.*;
  3. @Component
  4. public class MyBean {
  5. @Value("${name}")
  6. private String name;
  7. // ...
  8. }

在您的应用程序类路径(例如,在你jar)你可以有一个application.properties属性文件,为name属性提供合理的默认属性值. 当在一个新的环境中运行时,application.properties属性文件可以由你的jar之外提供,用于覆盖name属性.对于一次性的测试,您可以以特定的命令行启动(例如,java jar app.jar --name = "Spring").

Tip

SPRING_APPLICATION_JSON属性可以以环境变量的形式在命令行上提供.例如,您可以使用下面的命令在UN*X shell运行:
$ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java -jar myapp.jar
在前面的示例中,在Spring环境中你以acme.name=test结束.你也可以在系统属性中以spring.application.json参数提供JSON子串,如以下示例所示:
java -Dspring.application.json=' {“name”:“test”}’ -jar myapp.jar
你还可以使用命令行参数方式提供JSON,如以下所示:
$ java -jar myapp.jar --spring.application.json='{"name":"test"}'
当然,你还可以以JNDI变量提供JSON,如以下所示:
java:comp/env/spring.application.json