1. 引言

在Java应用后端开发中,随着项目的不断发展,应用需求的不断细化与添加,工程项目中的代码越来越多,项目结构越来越复杂,项目进展将会遇到各种问题:

  • 不同方面的代码之间相互耦合,这时候一旦应用出现问题很难定位到问题的出现原因,即使定位到问题也很难去修正问题,可能在修正问题的时候引入更多的问题;
  • 多方面的代码集中在一个整体结构中,新加入团队的开发人员很难对整体项目有直观的感受,增加了新手介入开发的成本,需要有一个熟悉整个项目的开发人员维护整个项目的结构(通常在项目较大且开发时间较长时这是很难做到的)。
  • 开发人员对自己或者他人负责的代码边界很模糊,这是复杂项目中最容易遇到的,导致的结果就是开发者很容易修改了他人负责的代码且代码负责人还不知道,责任追踪很麻烦。

因此将一个复杂项目拆分成多个模块是解决上述问题的一个重要方法,多模块的划分可以降低代码之间的耦合性(从类级别的耦合提升到jar包级别的耦合),而且每个模块的功能定位比较清晰(通过模块名或者模块文档),同时模块还规范了代码边界的划分,开发人员很容易通过功能模块确定自己所负责的内容。

但是通过项目多模块拆分也将会引入了一些问题, 项目中涉及应用配置的相关配置文件比较多,应用程序在不同的环境可能会有不同的配置,例如数据库连接、日志级别等,开发,测试,生产每个环境可能配置都不一致,这将会给系统运维带来诸多的麻烦。

随着Spring Boot开发框架的出现和广泛应用,Spring Boot由于其能够支持开发人员快速开发与配置的特性,使得其受广大开发人员的支持和应用。通过Spring Boot的Profile可以实现多场景下的配置切换,方便开发中进行测试和部署生产环境。 下面将大致介绍一下如何使用Spring Boot Profile配置文件配置不同环境的配置文件。

2. Spring Boot配置步骤

  1. 在Spring Boot项目下的application.yml或application.properties中添加配置项

application.yml

spring:
  profiles:
    active: dev

application.properties

spring.profiles.active: dev

spring.profiles.active: dev表示默认加载的就是开发环境的配置,如果dev换成test,则会加载测试环境的属性,以此类推。

注意: 如果spring.profiles.active没有指定值,那么只会使用没有指定spring.profiles文件的值,也就是只会加载通用的配置,也就是Spring Boot只会加载application.yml或application.properties的通用配置。

  1. 创建不同环境下的配置文件
    例如环境分为开发环境、测试环境和生产环境,创建如下文件:
  • 开发环境 : application-dev.ymlapplication-dev.properties
  • 测试环境:application-test.ymlapplication-test.properties
  • 生产环境:application-prod.ymlapplication-prod.properties

application.yml文件分为四部分,使用 --- 来作为分隔符,第一部分通用配置部分,表示三个环境都通用的属性,用spring.profiles指定了一个值(开发为dev,测试为test,生产为prod),这个值表示该段配置应该用在哪个profile里面。

例如, 我们在某个项目中根据不同的环境配置不同的数据库信息:

  • 开发环境
spring:
  datasource:
     name: druidDataSource
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.1.2:3306/myDB?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&useSSL=false
      username: user1
      password: 123456
      filters: stat,wall,config
      max-active: 50
      initial-size: 1
      max-wait: 6000
      min-idle: 1
      time-between-eviction-runs-millis: 6000
      min-evictable-idle-time-millis: 30000
      validation-query: select 'x'
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: true
      max-open-prepared-statements: 50
      max-pool-prepared-statement-per-connection-size: 20
  • 测试环境
spring:
  datasource:
     name: druidDataSource
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.20.2:3306/myTestDB?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&useSSL=false
      username: user1
      password: 123456
      filters: stat,wall,config
      max-active: 150
      initial-size: 1
      max-wait: 10000
      min-idle: 1
      time-between-eviction-runs-millis: 20000
      min-evictable-idle-time-millis: 100000
      validation-query: select 'x'
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: true
      max-open-prepared-statements: 100
      max-pool-prepared-statement-per-connection-size: 20
  • 生产环境
spring:
  datasource:
     name: druidDataSource
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://172.1.16.2:3306/myProdDB?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&useSSL=false
      username: prod1
      password: prod1234!@#
      filters: stat,wall,config
      max-active: 100
      initial-size: 1
      max-wait: 60000
      min-idle: 1
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
      validation-query: select 'x'
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: true
      max-open-prepared-statements: 50
      max-pool-prepared-statement-per-connection-size: 20
  1. 对应用进行打包操作后, 启动应用
    如果是部署到服务器的话,我们正常打成jar包,启动应用时Spring Boot通过application.yml或applcation.properties文件中的spring.profiles.active配置项加载相关环境的配置信息。除此之外, 我们可以通过 --spring.profiles.active=xxx来控制加载哪个环境的配置,参考命令如下:
# 表示使用开发环境的配置
java -jar xxx.jar --spring.profiles.active=dev 

# 表示使用测试环境的配置
java -jar xxx.jar --spring.profiles.active=test 

# 表示使用生产环境的配置
java -jar xxx.jar --spring.profiles.active=prod
  1. 添加扩展的配置文件信息
    在复杂项目中,我们有可能需要添加一些额外的扩展配置信息, Spring Boot支持项目添加扩展的配置文件, 假设我们在某个功能模块hurricane-ldap中配置需要进行LDAP认证的配置文件application-ldap.yml,我们可以在application.yml或application.properties文件中修改spring.profiles.active配置项, 如下所示:
spring:
     profiles:
        active: dev,ldap

3. 通过Mavan实现多环境配置打包

  1. 在pom.xml文件中添加多环境配置
<!-- Application Environment Setting -->
<profiles>
     <profile>
         <id>dev</id>
         <activation>
             <!-- Default Active Without Assign Parameter -->
             <activeByDefault>true</activeByDefault>
         </activation>
         <properties>
             <profileActive>dev</profileActive>
         </properties>
     </profile>
     <profile>
         <id>test</id>
         <properties>
             <profileActive>test</profileActive>
         </properties>
     </profile>
     <profile>
         <id>prod</id>
         <properties>
             <profileActive>prod</profileActive>
         </properties>
     </profile>
</profiles>

注: 配置文件中添加开发、测试和生产三个环境的配置, 其中应注意profileActive自定义配置项, 该配置项指明应用配置文件的名称, 此配置项将在application.yml或application.properties中应用。

  1. 修改applcation.yml或application.properties配置项
    修改applcation.yml或application.properties配置项,替换spring.profies.active配置项,如下所示:
spring:
    profiles:
       active: @profileActive@,ldap

注: @profileActive@为上一步骤中pom.xml文件配置的自定义配置项, 该参数可以根据开发人员自身的习惯进行命名和配置。

  1. 使用maven命令打包成相应环境的应用程序包
  • 生产环境
mvn clean package -Pprod -U  
# 或者
mvn clean package -DprofileActive=prod -U
  • 测试环境
mvn clean package -Ptest -U  
# 或者
mvn clean package -DprofileActive=test -U
  • 开发环境
mvn clean package -Pdev -U  
# 或者
mvn clean package -DprofileActive=dev -U