在上面的例子中,我们将Spring Boot应用需要的配置内容都放在了项目工程中,虽然我们已经能够通过spring.profiles.active或是通过Maven来实现多环境的支持。但是,当我们的团队逐渐壮大,分工越来越细致之后,往往我们不需要让开发人员知道测试或是生成环境的细节,而是希望由每个环境各自的负责人(QA或是运维)来集中维护这些信息。那么如果还是以这样的方式存储配置内容,对于不同环境配置的修改就不得不去获取工程内容来修改这些配置内容,当应用非常多的时候就变得非常不方便。同时,配置内容都对开发人员可见,本身这也是一种安全隐患。对此,现在出现了很多将配置内容外部化的框架和工具,后续将要介绍的Spring Cloud Config就是其中之一,为了后续能更好的理解Spring Cloud Config的加载机制,我们需要对Spring Boot对数据文件的加载机制有一定的了解。
Spring Boot为了能够更合理的重写各属性的值,使用了下面这种较为特别的属性加载顺序:
命令行中传入的参数。
SPRING_APPLICATION_JSON中的属性。SPRING_APPLICATION_JSON是以JSON格式配置在系统环境变量中的内容。
java:comp/env中的JNDI属性。
Java的系统属性,可以通过System.getProperties()获得的内容。
操作系统的环境变量
通过random.*配置的随机属性
位于当前应用jar包之外,针对不同{profile}环境的配置文件内容,例如:application-{profile}.properties或是YAML定义的配置文件
位于当前应用jar包之内,针对不同{profile}环境的配置文件内容,例如:application-{profile}.properties或是YAML定义的配置文件
位于当前应用jar包之外的application.properties和YAML配置内容
位于当前应用jar包之内的application.properties和YAML配置内容
在@Configuration注解修改的类中,通过@PropertySource注解定义的属性
应用默认属性,使用SpringApplication.setDefaultProperties定义的内容
优先级按上面的顺序有高到低,数字越小优先级越高。
可以看到,其中第7项和第9项都是从应用jar包之外读取配置文件,所以,实现外部化配置的原理就是从此切入,为其指定外部配置文件的加载位置来取代jar包之内的配置内容。通过这样的实现,我们的工程在配置中就变的非常干净,我们只需要在本地放置开发需要的配置即可,而其他环境的配置就可以不用关心,由其对应环境的负责人去维护即可。
2.x 新特性在Spring Boot 2.0中推出了Relaxed Binding 2.0,对原有的属性绑定功能做了非常多的改进以帮助我们更容易的在Spring应用中加载和读取配置信息。下面本文就来说说Spring Boot 2.0中对配置的改进。
配置文件绑定 简单类型在Spring Boot 2.0中对配置属性加载的时候会除了像1.x版本时候那样移除特殊字符外,还会将配置均以全小写的方式进行匹配和加载。所以,下面的4种配置方式都是等价的:
properties格式:
spring.jpa.databaseplatform=mysql spring.jpa.database-platform=mysql spring.jpa.databasePlatform=mysql spring.JPA.database_platform=mysqlyaml格式:
spring: jpa: databaseplatform: mysql database-platform: mysql databasePlatform: mysql database_platform: mysqlTips:推荐使用全小写配合-分隔符的方式来配置,比如:spring.jpa.database-platform=mysql
List类型在properties文件中使用[]来定位列表类型,比如:
spring.my-example.url[0]=http://example.com spring.my-example.url[1]=http://spring.io也支持使用逗号分割的配置方式,上面与下面的配置是等价的:
spring.my-example.url=http://example.com,而在yaml文件中使用可以使用如下配置:
spring: my-example: url: - -也支持逗号分割的方式:
spring: my-example: url: ,