[Day - 27] - Spring 环境管理思想与设计

Abstract

许多开发者势必会遇到一种状况,就是在上线前势必会先放到测试主机进行测试,我们称之开发环境(Develop Environment,但每次都要修改组态档(Config file)内部的DB连线资讯、配置档内容,今天小编就依照Spring所预设的区分测试环境的设定档,依照不同的环境可透过命令参数进行切换,这样开发者就可依照不同环境自动触发不同的组态档,今日小编所提供的范例切分三种环境,区分为DEV、UAT及PROD环境,小编仅提供设定方法进行介绍,主要为了让各位开发者离CI/CD会越离越近,现在就开始准备切割你的环境罗!

Principle Introduction

在每个专案都会预设一个application.properties或application.yml,故小编仅针对application.properties进行设计,此时专案的预设profile key为default,故Spring提供一项配置命令spring.profiles.active进行设置环境配置档索引名称,其相关联的配置档须遵循命名原则,故原生在通过部署的时候,可以通过指令java -jar XXX.jar --spring.profiles.active=dev进行组态档串接,但小编觉得这样太麻烦,如果没带预设环境参数,小编希望自动配置预设,故小编重新调整以下方法与Spring 原生环境配置对接,命名规则如下:

application-{profile}.properties

当我们切割出三项设定後,分别在内部放置环境属性参数(sea.food.system.environment),当系统启动时我们可得知目前所配置的参数为哪个设定档,相关档名配置如下(详细资讯请看范例程序码):

application name sea.food.system.environment
application-dev.properties Sea Food Development ENV
application-staging.properties Sea Food Staging ENV
application-prod.properties Sea Food Production ENV

由於此环境参数最後通过Map集合中的springProfile key进行替换,故我们须在预设的application.properties组态档中加上取代环境变数的参数,及加上替换的方法在build.gradle中,小编较少使用maven,但一样也是透过pom.xml进行配置profiles参数,可以进行参考,相关设定如下:

application.properties setting profiles parameter

  spring.profiles.active=@springProfile@
  
  ...
  ...

加入以下取代参数方法在build.gradle 中,以便若无配置系统环境参数依旧会吃预设的profile


  def seaFoodSpringProfile = System.getProperty("profile") ?: "dev"

  println('Build Sea Food System PROFILE : ' + seaFoodSpringProfile)

  bootRun {
      systemProperty 'spring.profiles.active', "${seaFoodSpringProfile}"
  }

  processResources {
      filter org.apache.tools.ant.filters.ReplaceTokens, tokens: [
              springProfile: seaFoodSpringProfile
      ]
  }

通过以上配置方式,我们就可以顺利的将Spring的环境参数概念优化到对应的专案自动化构建工具中罗。

Command Line Flow

小编提供以下测试指令及结果提供各位开发者作参考。

Run dev/stag/prod environment application without JAR file

 1. gradle bootRun -D profile=dev
 2. gradle bootRun -D profile=stag
 3. gradle bootRun -D profile=prod

Result sample

 01:27:48.269  INFO 34931 --- [           main] sw.spring.sample.config.SeaFooConfig     : *******************************************************
 01:27:48.270  INFO 34931 --- [           main] sw.spring.sample.config.SeaFooConfig     : *** Sync boot profile : [Sea Food Development ENV] ***
 01:27:48.271  INFO 34931 --- [           main] sw.spring.sample.config.SeaFooConfig     : *******************************************************

Build dev/stag/prod environment JAR boot file without test

1. gradle -Dprofile=dev clean build -x test
2. gradle -Dprofile=stag clean build -x test
3. gradle -Dprofile=prod clean build -x test

Build Jar Result sample

> Configure project :
Build Sea Food System PROFILE : prod

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.8.3/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 4s
6 actionable tasks: 6 executed

Structure

当系统启动後,会透过扩展的BaseParamFilterReader类别中read()方法,将所有环境变数档名称存入org.apache.tools.ant.filters.ReplaceTokens#tokens物件中(HashTable型态物件),此时我们透过命令提示字元进行替换环境参数,命令如下:

1. gradle -Dprofile=dev 
2. gradle -Dprofile=stag
3. gradle -Dprofile=dev

透过Gradle进行传递参数至org.apache.tools.ant.filters.ReplaceTokens中名为tokens参数进行过滤取得其对应配置档,其参数是一种HashTable型态物件,里面存取专案资源中所有环境变数档,并透过继承之ChainableReader介面中的chain()方法进行过滤参数及取得对应环境变数设定档,若找不到则都取用default的环境变数(application.properties)。

图一、Spring 环境变数替换流程图
image

Environment Information Monitor

JVM 设备监测环境资讯
image

image

Sample source

spring-sample-environment

Reference url

使用 spring.profiles.active 及 @profile 注解 动态化配置内部及外部配置

gradle打包spring boot的测试、正式war、jar包


<<:  Day 30: 资安的隐藏第六面项:AWS 合规 & 完赛心得

>>:  Day30: auto_ptr

Android Studio初学笔记-Day11-Checkbox

Checkbox(可复选按钮) Checkbox是可复选按钮,不同於前一章的RadioButton,...

[ 卡卡DAY 1 ] - React Native 一个 target 一个 start

背景与前言: 我是个转职的前端工程师,近期因专案需要开始写APP,基於我有React的基础,所以选择...

Flutter基础介绍与实作-Day26 旅游笔记的实作(7)

到昨天为止我们终於把美食的部分都做完了,再来要做的是美景的部分,其实做法跟前面的都差不多,我这边就会...

[DAY20] Domain 间的依赖关系

Domain 间的依赖 在专案中,除了 domain 内上下层的关系外,domain 之间也会有依赖...

C槽系统目录--Windows资料夹常识

从这篇开始,我们要介绍一些Windows系统常识,做为一个资工先了解Windows的系统结构,懂得问...