多环境配置
多环境配置
在构建环境之初,一个很重要的特性就是根据不同的环境自动使用不同的配置文件,从而完成譬如测试数据库与开发数据库的动态切换。而 Spring Boot 提供了一个非常好用的动态切换配置文件的方法,在 application.properties 文件中指定 spring.profiles.active
参数,那么 Spring 会自动在 classpath 或者 classpath:./config 目录下寻找 application-{profile}.properties
文件,并且将其中内容提取出来用作创建 Bean 的时候动态替换占位符。在命令行方式启动 Spring Boot 应用时,连续的两个减号 –就是对 application.properties 中的属性值进行赋值的标识。所以,java -jar xxx.jar --server.port=8888
命令,等价于我们在 application.properties 中添加属性 server.port=8888。
指定环境启动
通过命令行来修改属性值是 Spring Boot 非常重要的一个特性,通过此特性,理论上已经使得我们应用的属性在启动前是可变的,所以其中端口号也好、数据库连接也好,都是可以在应用启动时发生改变,而不同于以往的 Spring 应用通过 Maven 的 Profile 在编译器进行不同环境的构建。其最大的区别就是,Spring Boot 的这种方式,可以让应用程序的打包内容,贯穿开发、测试以及线上部署,而 Maven 不同 Profile 的方案每个环境所构建的包,其内容本质上是不同的。但是,如果每个参数都需要通过命令行来指定,这显然也不是一个好的方案,所以下面我们看看如果在 Spring Boot 中实现多环境的配置。
在 Spring Boot 中多环境配置文件名需要满足 application-{profile}.properties
的格式,其中 {profile}
对应你的环境标识,比如:
application-dev.properties
:开发环境application-test.properties
:测试环境application-prod.properties
:生产环境
至于哪个具体的配置文件会被加载,需要在 application.properties
文件中通过 spring.profiles.active
属性来设置,其值对应配置文件中的 {profile}
值。如:spring.profiles.active=test
就会加载 application-test.properties
配置文件内容。
application.properties
中配置通用内容,并设置spring.profiles.active=dev
,以开发环境为默认配置application-{profile}.properties
中配置各个环境不同的内容- 通过命令行方式去激活不同环境的配置
注意,2.4 版本之前,我们在 yaml 配置文件中,使用 spring.profiles 来定义不同环境的标识,比如下面这样。
spring:
profiles: "dev"
name: dev.didispace.com
---
spring:
profiles: "test"
name: test.didispace.com
---
spring:
profiles: "prod"
name: prod.didispace.com
而在本次 2.4 版本升级之后,我们需要将 spring.profiles 配置用 spring.config.activate.on-profile 替代,比如上面的配置需要修改为如下配置:
spring:
config:
activate:
on-profile: "dev"
name: dev.didispace.com
---
spring:
config:
activate:
on-profile: "test"
name: test.didispace.com
---
spring:
config:
activate:
on-profile: "prod"
name: prod.didispace.com
应用启动的时候,我们要加载不同的环境配置的参数不变,依然采用 spring.profiles.active 参数,对应值采用 spring.config.activate.on-profile 定义的标识名称。比如下面的命令就能激活 dev 环境的配置。
java -jar myapp.jar -Dspring.profiles.active=dev
我们也可以将 spring.profiles.active 写入 yaml 配置中,这样的作用就可以指定默认使用某一个环境的配置,通常我们可以设置成开发环境,这样有利于我们平时的开发调试,而真正部署到其他环境的时候则多以命令参数激活为主。
spring:
profiles:
active: "dev"
默认配置文件
Spring Boot 的默认配置文件位置为:src/main/resources/application.properties
。关于 Spring Boot 应用的配置内容都可以集中在该文件中了,根据我们引入的不同 Starter 模块,可以在这里定义诸如:容器端口名、数据库链接信息、日志级别等各种配置信息。比如,我们需要自定义 web 模块的服务端口号,可以在 application.properties 中添加 server.port=8888 来指定服务端口为 8888,也可以通过 spring.application.name=hello 来指定应用名(该名字在 Spring Cloud 应用中会被注册为服务名)。
配置加载顺序
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 包之内的配置内容。通过这样的实现,我们的工程在配置中就变的非常干净,我们只需要在本地放置开发需要的配置即可,而其他环境的配置就可以不用关心,由其对应环境的负责人去维护即可。