spring配置加载顺序

spring的配置加载顺序


Spring 使用了特定的配置属性加载顺序,目的在利用一些约定的配置提升框架的易用性之外,也可以被用户自定义覆盖。
下面是优先级顺序, 前面的可以覆盖后面的配置:

  • Command line arguments.
  • Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
  • JNDI attributes from java:comp/env.
  • Java System properties (System.getProperties()).
  • OS environment variables.
  • A RandomValuePropertySource that only has properties in random.*.
  • Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
  • Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
  • Application properties outside of your packaged jar (application.properties and YAML variants).
  • Application properties packaged inside your jar (application.properties and YAML variants).
  • @PropertySource annotations on your @Configuration classes.
  • Default properties (specified using SpringApplication.setDefaultProperties).

配置覆写测试和验证


使用starter-web来测试:

@Controller
@EnableAutoConfiguration
public class SampleController {

@Value("${myname}")
String myName;

@RequestMapping("/")
@ResponseBody
String home() {
return "Hello, " + myName;
}

public static void main(String[] args) throws Exception {
SpringApplication.run(SampleController.class, args);
}
}

测试用命令行传入:

java -jar target/app.jar --myname="niko"

结果是:Hello, niko

测试 shell 环境变量和 java 系统变量

export SPRING_APPLICATION_JSON='{"myname": "niko_shell_env"}'
java -jar target/app.jar --myname="niko"

or
java -jar target/app.jar -Dspring.application.json='{"myname": "niko_shell_env"}' --myname="niko"

or
java -jar myapp.jar --spring.application.json='{"myname": "niko_shell_env"}' --myname="niko"

结果是:Hello, niko, 被命令行覆盖了。

测试application.properties

application.properties:

spring.profiles.active=dev
myname=application.properties

java -jar myapp.jar -Dspring.application.json='{"myname": "niko_shell_env"}'

结果是:Hello, niko_shell_env, 被-Dspring.application.json覆盖了。SPRING_APPLICATION_JSON 和 --spring.application.json 结果一样。

值得注意的是 SPRING_APPLICATION_JSON 是会被 -Dspring.application.json 覆盖的。

取消掉环境变量和系统变量后,结果是:Hello, application.properties

测试 config/application-dev.properties:

myname=application-dev.properties

结果是:Hello, application-dev.propertiesapplication.propertiesconfig/application-dev.properties 覆盖了。

其他细节

application.properties 的查找顺序

Spring会加载配置文件application.properties从以下位置:

  • A /config subdirectory of the current directory.
  • The current directory
  • A classpath /config package
  • The classpath root

如果你不喜欢application这个name,可以传入--spring.config.name=othername来设置,或者是使用--spring.config.location=classpath:/default.properties,classpath:/override.properties
值得注意的是,spring.config.location声明的加载优先级是从低到高,即是会先加载classpath:/override.properties

占位符使用

application.properties

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

这个就算是app.name的声明顺序倒过来也是okay的。

部署小技巧

部署时, 可以把 application.properties 放在 jar 包之外(用 -cp path1:path2 方式指定), 这样修改配置会比较方便。而不必打开 spring boot jar(在生产环境也不容易解压和重打包)。

参考


http://docs.spring.io/autorepo/docs/spring-boot/1.3.0.M1/reference/html/boot-features-external-config.html
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html