Maven的porfile與SpringBoot的profile結合使用完成多環境配置文件切換 詳解
一.Maven的porfile
首先弄清楚Maven的profile
1.pom.xml增加多環境配置

<!-- 多環境配置 start -->
<profiles>
<!-- local一般作為開發者開發的環境 -->
<profile>
<id>sxdlocal</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sxdProfileActive>local</sxdProfileActive>
</properties>
</profile>
<!-- dev一般作為開發者穩定的自測環境 -->
<profile>
<id>dev</id>
<properties>
<sxdProfileActive>dev</sxdProfileActive>
</properties>
</profile>
<!-- uat環境一般作為業務驗收環境 -->
<profile>
<id>uat</id>
<properties>
<sxdProfileActive>uat</sxdProfileActive>
</properties>
</profile>
<!-- test環境作為測試環境 -->
<profile>
<id>test</id>
<properties>
<sxdProfileActive>test</sxdProfileActive>
</properties>
</profile>
<!-- online環境作為生產環境 -->
<profile>
<id>online</id>
<properties>
<sxdProfileActive>online</sxdProfileActive>
</properties>
</profile>
<!-- backUp作為 2021.07.23分環境之前的一個備份穩定配置 -->
<profile>
<id>myBackUp</id>
<properties>
<sxdProfileActive>backup</sxdProfileActive>
</properties>
</profile>
</profiles>
<!-- 多環境配置 end -->
官網地址屬性說明:https://maven.apache.org/ref/3.8.1/maven-model/maven.html#class_activation
說明:
<profiles> //包含多種profile <profile> //可以基於環境參數 或 命令行參數中 指定的ID 激活的構建過程的修改 <id>sxdlocal</id> //IDEA的MAVEN組件中展示的profile值 或 命令行中 -P后指定的profile值 <activation> //激活標簽 <activeByDefault>true</activeByDefault> //默認激活該profile對應的配置文件,如果命令行-P指定了 或 IDEA勾選了,則以實際指定或勾選的為准 </activation> <properties> //屬性標簽 內部包含<key>value</key> key是可以自己指定的 <sxdProfileActive>local</sxdProfileActive> </properties> </profile> </profiles>
2.build標簽中的resource標簽的filtering屬性一定要設置為true

<!-- build標簽描述了如何來編譯及打包項目 參考地址:https://blog.csdn.net/u010010606/article/details/79727438 --> <build> <!-- 而具體的編譯和打包工作是通過build中配置的 plugin 來完成 --> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <version>2.6</version> <artifactId>maven-resources-plugin</artifactId> <configuration> <encoding>UTF-8</encoding> <nonFilteredFileExtensions> <nonFilteredFileExtension>xlsx</nonFilteredFileExtension> </nonFilteredFileExtensions> </configuration> </plugin> </plugins> <!-- build過程中涉及的資源文件 用於包含 或 排除某些資源文件 --> <resources> <resource> <!-- 資源文件的路徑,默認位於${basedir}/src/main/resources/目錄下 --> <directory>src/main/resources</directory> <filtering>true</filtering> <!-- 一組文件名的匹配模式,被匹配的資源文件將被構建過程忽略。同時被includes和excludes匹配的資源文件,將被忽略。 --> <excludes> <exclude>**/*.ttf</exclude> <exclude>**/*.woff</exclude> </excludes> </resource> </resources> </build>
為什么一定要設置為 true ??下面通過作用闡明 和 舉例子解釋
2.1 filtering標簽的作用
官網說明地址:https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
filtering作用即 設置為true代表打通pom.xml和 <directory>指定路徑下的文件之間的通道。(該目錄下一般都是配置文件yml或properties,也可以是txt等其他)
解析第一種:使得<directory>指定路徑下的配置文件中以${}表達式定義的變量,可以從pom.xml文件中獲取到對應標簽變量去完成文本替換。
解析第二種:或者替換<directory>指定路徑下的配置文件中以@sxdProfileActive@表達式定義的變量
2.2 ${}表達式替換 舉例
使得<directory>指定路徑下的配置文件中以${}表達式定義的變量,可以從pom.xml文件中獲取到對應標簽變量去完成文本替換。
例如:
pom.xml文件中定義了標簽
<name>張三</name>
配置文件(properties/yml/txt/...等所有在<directory>指定路徑下的文件)中定義
spring.myname=${name}
則maven編譯完成后,配置文件中的結果為
spring.myname=張三
2.3 @xxx@表達式 舉例
或者替換<directory>指定路徑下的配置文件中以@sxdProfileActive@表達式定義的變量
例如:
pom.xml文件中定義了
<profile> <id>dev</id> <properties> <sxdProfileActive>dev</sxdProfileActive> </properties> </profile>
application.properties文件中定義的
spring.profiles.active=@sxdProfileActive@
則maven編譯完成后,application.properties配置文件中的結果為
spring.profiles.active=dev
2.4 如果filtering就設置為false,表現會是怎樣
所以,多環境profile切換配置文件情況下,該標簽必須設置為true,否則拿上面第二個例子看,就會導致
spring.profiles.active=@sxdProfileActive@
不能完成正常的值替換,
從而導致applocation-{profile}.properties匹配不到對應的profile的配置文件,
從而默認加載application.properties主配置文件。
而主配置文件中毛配置都沒有,(下面的Springboot 的 profile會把多環境的配置文件內容貼出來,以下面貼出來為例)
最終導致 java代碼中的@Bean/@Configuration 中用到配置文件中的配置才能完成初始化的動作 就會失敗。
例如:
java代碼初始化這樣的一個Configuration
@Configuration public class DruidDBConfig { @Value("${spring.datasource.url}") private String dbUrl; ...... }
,如果設置為false,最終表現便是 啟動時 報錯如下:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'druidDBConfig':
Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.url' in value "${spring.datasource.url}"
3.pom.xml增加多環境配置后 IDEA Maven顯示的Profiles即已增加的多環境配置顯示
4.Maven的命令查看 mvn -P代表的含義
mvn --help
-P即 代表
mvn --activate-profiles dev
5.所以,Maven的profile怎么生效
5.1 本地
即可通過 IDEA Maven顯示的Profiles 的切換勾選,完成maven 的 profiles.active 的值切換
勾選,即以勾選的生效profile,全不勾選,則以pom.xml多環境配置中設置了
<activeByDefault>true</activeByDefault>
的生效profile
5.2 test/online服務器端
可以配置maven打包命令 -P 指明profiles.active
如下,指定生效的profile為 pom.xml文件中 ID = test的profile生效。
mvn clean package install -P test -Dmaven.test.skip=true -U
同理,如果未設置 -P,則默認以pom.xml多環境配置中設置了
<activeByDefault>true</activeByDefault>
的生效profile
二.SpringBoot的profile
1.如果不和maven的profile聯動,正常SpringBoot切換profile完成多環境配置切換,是什么樣?
正常簡陋原始一點,本機開發時候就在application.properties主配置文件寫死
spring.profiles.active = local
上測試環境,就修改application.properties主配置文件
spring.profiles.active = test
上不同環境就得手動去變更。
2.Maven的profile 和 Spring boot的profile聯動
Maven的profile 和 Spring boot的profile聯動,達到開發一次,多環境自動編譯時加載並生效不同profile對應的配置文件的效果。
2.1 配置文件代碼
application.properties
spring.profiles.active=@sxdProfileActive@
application-local.properties

server.port=9666 spring.jackson.time-zone=GMT+8 #spring boot2.0 限制文件上傳大小【spring boot默認1MB】 spring.servlet.multipart.max-file-size=90MB spring.servlet.multipart.max-request-size=100MB #datasource 單數據源 spring.datasource.continue-on-error=false #=========本地=========== spring.datasource.url=jdbc:mysql://localhost:3306/swapping?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8 #=======虛擬機========== #spring.datasource.url=jdbc:mysql://192.168.92.130:3306/swapping?useSSL=false&useUnicode=true&characterEncoding=UTF-8 spring.datasource.username=root spring.datasource.password=mynewpassword123 #druid 下面為連接池的補充設置,應用到上面所有數據源中 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver # 初始化大小,最小,最大 spring.datasource.initialSize=5 spring.datasource.minIdle=5 spring.datasource.maxActive=20 # 配置獲取連接等待超時的時間 spring.datasource.maxWait=60000 # 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 spring.datasource.timeBetweenEvictionRunsMillis=60000 # 配置一個連接在池中最小生存的時間,單位是毫秒 spring.datasource.minEvictableIdleTimeMillis=300000 spring.datasource.validationQuery=SELECT 'x' spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=false # 打開PSCache,並且指定每個連接上PSCache的大小 spring.datasource.poolPreparedStatements=true spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 spring.datasource.maxOpenPreparedStatements=20 # 配置監控統計攔截的filters,去掉后監控界面sql無法統計,'wall'用於防火牆 spring.datasource.filters=stat,wall,log4j # 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄 spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 合並多個DruidDataSource的監控數據 #spring.datasource.useGlobalDataSourceStat=true #mybatis相關配置 參考地址:https://mybatis.org/mybatis-3/zh/index.html #mybatis映射文件的位置 mybatis.mapper-locations=classpath:mapper/*.xml #mybatis指定entity位置 mybatis.type-aliases-package=com.sxd.swapping.mybatis.pojo #mybatis展示sql語句執行 logging.level.com.sxd.swapping=debug #允許 JDBC 支持自動生成主鍵,需要數據庫驅動支持。如果設置為 true,將強制使用自動生成主鍵。盡管一些數據庫驅動不支持此特性,但仍可正常工作 mybatis.configuration.use-generated-keys=true #是否開啟駝峰命名自動映射,即從經典數據庫列名 A_COLUMN 映射到經典 Java 屬性名 aColumn mybatis.configuration.map-underscore-to-camel-case=true #pagehelper mybatis分頁插件 pagehelper.helperDialect=mysql pagehelper.reasonable=true pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql pagehelper.returnPageInfo=check #jpa相關配置 spring.jpa.database=mysql spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update spring.jpa.database-platform=org.hibernate.dialect.MySQL55Dialect #redis配置 # Redis數據庫索引(默認為0) spring.redis.database=0 # Redis服務器地址 #======本地======= spring.redis.host=localhost #=======虛擬機======= #spring.redis.host=192.168.92.130 # Redis服務器連接端口 spring.redis.port=6379 # Redis服務器連接密碼(默認為空) spring.redis.password=398023 # 連接池最大連接數(使用負值表示沒有限制) spring.redis.jedis.pool.max-active=8 # 連接池最大阻塞等待時間(使用負值表示沒有限制) spring.redis.jedi.pool.max-wait=-1 # 連接池中的最大空閑連接 spring.redis.jedi.pool.max-idle=8 # 連接池中的最小空閑連接 spring.redis.jedi.pool.min-idle=0 # 連接超時時間(毫秒) spring.redis.jedi.timeout=0 #elasticsearch相關配置 #es的cluster集群名稱可以查看服務器安裝的集群名稱 curl http://192.168.92.130:9200 獲取到集群名稱 spring.data.elasticsearch.cluster-name=docker-cluster #注意端口為9300 9300 是 Java 客戶端的端口,支持集群之間的通信。9200 是支持 Restful HTTP 的接口 spring.data.elasticsearch.cluster-nodes=192.168.92.130:9300 #logback對接logstash的日志配置文件 logging.config=classpath:logback-spring.xml #線程池配置 thread.pool.core.size=10 thread.pool.max.size=10 thread.pool.queue.capacity=10000 thread.pool.alive.seconds=1000
application-test.proerties

server.port=9669 spring.jackson.time-zone=GMT+8 #spring boot2.0 限制文件上傳大小【spring boot默認1MB】 spring.servlet.multipart.max-file-size=90MB spring.servlet.multipart.max-request-size=100MB #datasource 單數據源 spring.datasource.continue-on-error=false #=========本地=========== spring.datasource.url=jdbc:mysql://localhost:3306/swapping?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8 #=======虛擬機========== #spring.datasource.url=jdbc:mysql://192.168.92.130:3306/swapping?useSSL=false&useUnicode=true&characterEncoding=UTF-8 spring.datasource.username=root spring.datasource.password=mynewpassword123 #druid 下面為連接池的補充設置,應用到上面所有數據源中 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver # 初始化大小,最小,最大 spring.datasource.initialSize=5 spring.datasource.minIdle=5 spring.datasource.maxActive=20 # 配置獲取連接等待超時的時間 spring.datasource.maxWait=60000 # 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 spring.datasource.timeBetweenEvictionRunsMillis=60000 # 配置一個連接在池中最小生存的時間,單位是毫秒 spring.datasource.minEvictableIdleTimeMillis=300000 spring.datasource.validationQuery=SELECT 'x' spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=false # 打開PSCache,並且指定每個連接上PSCache的大小 spring.datasource.poolPreparedStatements=true spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 spring.datasource.maxOpenPreparedStatements=20 # 配置監控統計攔截的filters,去掉后監控界面sql無法統計,'wall'用於防火牆 spring.datasource.filters=stat,wall,log4j # 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄 spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 # 合並多個DruidDataSource的監控數據 #spring.datasource.useGlobalDataSourceStat=true #mybatis相關配置 參考地址:https://mybatis.org/mybatis-3/zh/index.html #mybatis映射文件的位置 mybatis.mapper-locations=classpath:mapper/*.xml #mybatis指定entity位置 mybatis.type-aliases-package=com.sxd.swapping.mybatis.pojo #mybatis展示sql語句執行 logging.level.com.sxd.swapping=debug #允許 JDBC 支持自動生成主鍵,需要數據庫驅動支持。如果設置為 true,將強制使用自動生成主鍵。盡管一些數據庫驅動不支持此特性,但仍可正常工作 mybatis.configuration.use-generated-keys=true #是否開啟駝峰命名自動映射,即從經典數據庫列名 A_COLUMN 映射到經典 Java 屬性名 aColumn mybatis.configuration.map-underscore-to-camel-case=true #pagehelper mybatis分頁插件 pagehelper.helperDialect=mysql pagehelper.reasonable=true pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql pagehelper.returnPageInfo=check #jpa相關配置 spring.jpa.database=mysql spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update spring.jpa.database-platform=org.hibernate.dialect.MySQL55Dialect #redis配置 # Redis數據庫索引(默認為0) spring.redis.database=0 # Redis服務器地址 #======本地======= spring.redis.host=localhost #=======虛擬機======= #spring.redis.host=192.168.92.130 # Redis服務器連接端口 spring.redis.port=6379 # Redis服務器連接密碼(默認為空) spring.redis.password=398023 # 連接池最大連接數(使用負值表示沒有限制) spring.redis.jedis.pool.max-active=8 # 連接池最大阻塞等待時間(使用負值表示沒有限制) spring.redis.jedi.pool.max-wait=-1 # 連接池中的最大空閑連接 spring.redis.jedi.pool.max-idle=8 # 連接池中的最小空閑連接 spring.redis.jedi.pool.min-idle=0 # 連接超時時間(毫秒) spring.redis.jedi.timeout=0 #elasticsearch相關配置 #es的cluster集群名稱可以查看服務器安裝的集群名稱 curl http://192.168.92.130:9200 獲取到集群名稱 spring.data.elasticsearch.cluster-name=docker-cluster #注意端口為9300 9300 是 Java 客戶端的端口,支持集群之間的通信。9200 是支持 Restful HTTP 的接口 spring.data.elasticsearch.cluster-nodes=192.168.92.130:9300 #logback對接logstash的日志配置文件 logging.config=classpath:logback-spring.xml #線程池配置 thread.pool.core.size=10 thread.pool.max.size=10 thread.pool.queue.capacity=10000 thread.pool.alive.seconds=1000
各環境的配置文件,咱么就以不同端口號 區分一下,后面啟動時候,選擇不同maven的profile,則啟動后加載勾選的proflie對應的properties文件
例如,勾選local
啟動,則端口為
例如,勾選test
重新啟動
2.2 聯動的原理是啥呢?
①首選pom.xml配置了多環境配置
②IDEA指定勾選 和 服務器端 mvn -P test 指定maven的profile對應的ID
③服務啟動/打包編譯時候,便根據maven的profile對應的ID 找到對應的<profile>標簽,並加載到了內部的<properties>標簽
④此時,<build>標簽中的<resources>中的<resource>下,<filtering>一定是設置為true,開啟了pom和配置文件之間的通道
⑤然后將對應的<profile>標簽中加載到的<properties>標簽中的自定義key - value拿上,去找到application.properties中的@XXX@ 或 ${}表達式
⑥spring.profiles.active=@sxdProfileActive@,並根據key為sxdProfileActive,做了value的替換,最終編譯完成,application.properties中的 spring.profiles.active=local
⑦如此,應用在啟動中,就根據 spring.profiles.active=local,成功加載上了 application-local.properties 文件
⑧最終,完成了 maven的profile和 springboot的profile的聯動替換。
====================
完。