多环境配置

多环境配置

在构建环境之初,一个很重要的特性就是根据不同的环境自动使用不同的配置文件,从而完成譬如测试数据库与开发数据库的动态切换。而 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 为了能够更合理的重写各属性的值,使用了下面这种较为特别的属性加载顺序:

  1. 命令行中传入的参数。
  2. SPRING_APPLICATION_JSON 中的属性。SPRING_APPLICATION_JSON 是以 JSON 格式配置在系统环境变量中的内容。
  3. java:comp/env 中的 JNDI 属性。
  4. Java 的系统属性,可以通过 System.getProperties() 获得的内容。
  5. 操作系统的环境变量
  6. 通过 random.* 配置的随机属性
  7. 位于当前应用 jar 包之外,针对不同 {profile}环境的配置文件内容,例如:application-{profile}.properties 或是 YAML 定义的配置文件
  8. 位于当前应用 jar 包之内,针对不同 {profile}环境的配置文件内容,例如:application-{profile}.properties 或是 YAML 定义的配置文件
  9. 位于当前应用 jar 包之外的 application.propertiesYAML配置内容
  10. 位于当前应用 jar 包之内的 application.propertiesYAML配置内容
  11. @Configuration注 解修改的类中,通过 @PropertySource 注解定义的属性
  12. 应用默认属性,使用 SpringApplication.setDefaultProperties 定义的内容

优先级按上面的顺序有高到低,数字越小优先级越高。可以看到,其中第 7 项和第 9 项都是从应用 jar 包之外读取配置文件,所以,实现外部化配置的原理就是从此切入,为其指定外部配置文件的加载位置来取代 jar 包之内的配置内容。通过这样的实现,我们的工程在配置中就变的非常干净,我们只需要在本地放置开发需要的配置即可,而其他环境的配置就可以不用关心,由其对应环境的负责人去维护即可。

下一页