使用Spring Boot Profile实现多环境配置

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 
    
  2. 添加扩展的配置文件信息

    在复杂项目中,我们有可能需要添加一些额外的扩展配置信息, 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中应用。

  2. 修改applcation.yml或application.properties配置项

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

    spring:
        profiles:
           active: @profileActive@,ldap
    

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

  3. 使用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
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容