Maven Profile 與 SpringBoot Profile 多環境打包指派指定環境

目錄

1、使用場景

2、Spring Boot Profile

3、Maven Profile設置

4、Spring profile與Maven Profile 融合二者,取長補短 實現 多環境打包

5、成果展現

6、總結

7、參考文章


1、使用場景

        因爲實際項目之中,經常使用到針對不同環境進行相關的打包。於是趁最近一段時間比較閒。研究了一下如何是現在在多環境下打包問題。本片文章實現了基於*.properties文件及 *.yml文件的多環境打包。本片文章使用的是基於Maven的Profile,同時使用Maven的過濾器(filtering)。

      一般開發團隊會有多個部署環境,如 dev 環境用於開發自測,Test環境讓測試團隊測試, Production 環境作爲線上環境。通常不同環境的配置不同,我們希望打包時的人力消耗最少。

需要注意下:本文裏面雖然都實現了*.properties和.yml文件的多環境下指定某個環境進行打包。但是有一個問題比較糟心就是基於*.properties文件類型的多環境打包時候,在application.properties文件之中中文被轉換爲了 Unicode碼。希望其他看到此文的人能夠提供好的解決方案。雖然功能可以實現指定環境直接替換,這是唯一的缺陷。

其他的.yml文件的替換很正常的。

2、Spring Boot Profile

     Spring Boot Profile 有許多的功能,這裏只說管理配置的內容。Spring 加載配置的順序如下:

  1. Jar 包外的 application-{profile}.properties
  2. Jar 包內的 application-{profile}.properties
  3. Jar 包外的 application.properties
  4. Jar 包內的 application.properties

   例如,如果我們在 application.properties 中指

spring.profiles.active = prod

則 SpringBoot 會使用 application-prod.properties 文件中的配置來覆蓋 application.properties 文件中的相應配置。

3、Maven Profile設置

Maven 也提供了 Profile 支持,它允許我們在 pom.xml 中定義多個 Profile ,

每個 profile 可以指定自己的一些配置、依賴、觸發條件等。例如:

<profiles>
	<profile>
		<id>dev</id><!-- 開發環境 -->
		<properties>
			<active.target.profile>dev</active.target.profile>
		</properties>
	</profile>
	<profile>
		<id>test</id><!-- 測試環境 -->
		<properties>
			<active.target.profile>test</active.target.profile>
		</properties>
	</profile>
	<profile>
		<id>prod_test</id><!-- 生測環境 -->
		<properties>
			<active.target.profile>prod_test</active.target.profile>
		</properties>
	</profile>
	<profile>
		<id>prod</id><!-- 生產環境 -->
		<properties>
			<active.target.profile>prod</active.target.profile>
		</properties>
		<activation>
			<activeByDefault>true</activeByDefault>
		</activation>
	</profile>
</profiles>

上面指定了四個 profile: dev、test、prod_test、prod,其中 prod是默認啓用的,當profile 被啓用時,它定義的的屬性、依賴等內容就會起效。這裏我們定義了spring.profiles.active 屬性(可以自己命名爲其他的只要對應上關係即可),之後會用到。

在編譯時指定 mvn clean install -Pprod 就能切換成 prod profile。

4、Spring profile與Maven Profile 融合二者,取長補短 實現 多環境打包

Maven 與 Spring Profile 的功能是有重合的,只使用一種其實就能實現多環境多配置。但它們各有千秋:

  • Spring profile 除了指定配置,還有一些其它作用(如爲不同的 profile 生成不同的 bean),但每次打包前都需要手工指定啓用哪個 profile
  • Maven Profile 可以通過命令行指定使用的 profile,但缺少了 spring profile 的一 些特定功能。

在 pom.xml 中定義 Profile

這裏跟上面介紹的一樣,定義兩個/多個 profile 併爲各個 profile 指定自己的屬性:

<profiles>
	<profile>
		<id>dev</id><!-- 開發環境 -->
		<properties>
			<active.target.profile>dev</active.target.profile>
		</properties>
	</profile>
	<profile>
		<id>test</id><!-- 測試環境 -->
		<properties>
			<active.target.profile>test</active.target.profile>
		</properties>
	</profile>
	<profile>
		<id>prod_test</id><!-- 生測環境 -->
		<properties>
			<active.target.profile>prod_test</active.target.profile>
		</properties>
	</profile>
	<profile>
		<id>prod</id><!-- 生產環境 -->
		<properties>
			<active.target.profile>prod</active.target.profile>
		</properties>
		<activation>
			<activeByDefault>true</activeByDefault>
		</activation>
	</profile>
</profiles>

在 pom.xml 中定義資源過濾

目的是爲了讓 maven 在構建時用 profile 中指定的屬性來替換 application.properties 中的內容。

<resources>
	<resource>
		<directory>src/main/resources</directory>
		<!--1 先排除所有的profile文件 -->
		<excludes>
			<exclude>application*.properties</exclude>
			<!--
			<exclude>application*.yml</exclude>
			-->
		</excludes>
	</resource>
	<resource>
		<directory>src/main/resources</directory>
		<!--2 按需複製所有需的profile文件-->
		<filtering>true</filtering>
		<includes>					
			<include>application.properties</include>
			<include>application-${spring.profiles.active}.properties</include>
			<!--
			<include>application.yml</include>
			<include>application-${spring.profiles.active}.yml</include>
			-->
		</includes>
	</resource>
</resources>

1位置中,我們通過 excludes 來將所有的 application*.properties(application*.yml) 排除在外,這樣 maven 在打包時就不會複製這些文件。畢竟我們不希望把 application-dev.properties 也包含在 prod 的 jar 包裏。

2位置中,通過開啓 filtering,maven 會將文件中的 #XX# 替換 profile 中定義的 XX 變量/屬性。另外,我們還通過 includes 來告訴 maven 根據profile 來複制對應的 propertie(yml)文件。

用 Maven 變量指定 Spring Profile

在 application.properties 文件中加入下面這行:

# 多環境配置文件激活屬性
spring.profiles.active=#active.target.profile#

這裏 active.target.profile 是在 maven profile 中的 properties 定義的,而 #XX# 的語法則是上節提到的 maven filtering 替換變量的語法。

構建不同的包

mvn clean package -P<profile_name>

5、成果展現

   此你可以在你的Ide開發環境之中運行,及可以看見很方便的切換當前啓動的環境。爲了顯示當前運行環境,寫了一個controller方法返回當前運行環境

@RestController
public class HelloController {

    @Autowired
    private Environment env;

    @RequestMapping("/hello")
    public String index() {
        return "Hello World";
    }

    @RequestMapping("/getCurrentEnv")
    public String getCurrentEnv(){
        String[] actProfile = env.getActiveProfiles();
        String curProfile = actProfile[0];
        return curProfile;
    }

}

IDE之中運行後如下圖所示:

使用打包工具打包後啓動一下試一試(本次選擇test環境了):

此時此目錄下只有兩個所需的.propertie文件

再看看打包後的jar文件之中

訪問一下當前的頁面

到此已經實現指定切換多環境下打包對應的環境,同時也不用在運行微服務時候指定環境啦。

示例源碼所在地址:https://github.com/jianxia612/StudySampleJava/tree/master/Chapter-Muti-Profiles

6、總結

Maven profile 與 Spring profile 有自的優點,結合起來的步驟如下:

  1. 在 pom.xml 中定義多個 profile 及自己的屬性
  2. 在 pom.xml 中定義 resource filtering,一方面控制 jar 中包含的資源文件, 一方面允許 @XX@ 的變量替換
  3. 在 application.properties 中指定 spring.profiles.active,值爲 maven profile 中定義的屬性。
  4. 構建時使用 mvn clean package -P<profile> 來指定 profile。
  5. 如果你不想使用@服務作爲過濾器符號,你可以自定義一個 需要在pom裏面配置即可如下
<properties>
	<!-- delimiter that doesn't clash with Spring ${} placeholders -->
	<!--
	<resource.delimiter>#</resource.delimiter>
	-->
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	<java.version>1.8</java.version>
</properties>

注意:問此還實現了基於yaml文件的過濾,示例工程之中放開對應的yaml文件,然後註釋掉properties 文件即可。另外需要把yaml文件目錄之中文件複製到resources下即可。

7、參考文章

Maven Profile 與 Spring Profile 管理多環境打包

Spring-Boot application.yml 文件拆分,實現 maven 多環境動態啓用 Profiles

spring boot通過maven filter替換properties屬性(多環境配置)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章