多环境配置

多环境配置

在构建环境之初,一个很重要的特性就是根据不同的环境自动使用不同的配置文件,从而完成譬如测试数据库与开发数据库的动态切换。而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应用通过MavenProfile在编译器进行不同环境的构建。其最大的区别就是,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包之内的配置内容。通过这样的实现,我们的工程在配置中就变的非常干净,我们只需要在本地放置开发需要的配置即可,而其他环境的配置就可以不用关心,由其对应环境的负责人去维护即可。

下一页