Maven管理SpringBoot Profile

chadLi發表於2017-10-30

1. Spring Profile

Spring可使用Profile決定程式在不同環境下執行情況,包含配置、載入Bean、依賴等。
Spring的Profile一般專案包含:dev(開發), test(單元測試), qa(整合測試), prod(生產環境)。由spring.profiles.active屬性決定啟用的profile。
SpringBoot的配置檔案預設為 application.properties(或yaml,此外僅以properties配置為說明)。不同Profile下的配置檔案由application-{profile}.properties管理,同時獨立的 Profile配置檔案會覆蓋預設檔案下的屬性。

2. Maven Profile

Maven同樣也有Profile設定,可在構建過程中針對不同的Profile環境執行不同的操作,包含配置、依賴、行為等。
Maven的Profile由 pom.xml 的<Profiles>標籤管理。每個Profile中可設定:id(唯一標識), properties(配置屬性), activation(自動觸發的邏輯條件), dependencies(依賴)等。
此文章不對Spring和Maven的Profile作過多說明,詳細情況請自行查閱。

3. Maven 管理 Spring Profile

由於構建是基於Maven(或Gradle,此處僅以Maven說明)。所以使用Maven管理Spring構建時的Profile是非常方便的。
Maven管理Spring Profile分五步,以下詳細介紹。

3.1 去掉預設的 Tomcat依賴

在SpringBoot MVC專案中,預設以內嵌Tomcat執行,如果需要特殊的設定或者使用Undertow,需要去掉預設的Tomcat依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

如果你同時使用了 MyBatis,需要去掉tomcat-jdbc依賴:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jdbc</artifactId>
        </exclusion>
    </exclusions>
</dependency>

3.2 Maven Profile設定

在專案(如果有模組為具體模組)的pom.xml下設定:

<!-- Maven控制Spring Profile -->
<profiles>
    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <profileActive>dev</profileActive>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </dependency>
            <dependency>
                <groupId>org.apache.tomcat</groupId>
                <artifactId>tomcat-jdbc</artifactId>
            </dependency>
        </dependencies>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <profileActive>prod</profileActive>
        </properties>
    </profile>
</profiles>

從上面的配置可以看出,Maven的Profile配置了兩個:dev和prod,並且在dev中使用了內嵌Tomcat,而 prod 中沒有,所以這兩個Profile打包的檔案dev可以直接執行(Plugin使用了SpringBoot Plugin),而prod並不能直接執行(或部署在外部Tomcat下,並不推薦這樣,後面會說明)。
properties中的profileActive是我們申明的屬性,此處對應Spring的Profile值。

3.3 Maven資源過濾

SpringBoot的 Profile選擇需要在 application.properties中配置,如果定死在檔案,那麼每次打包都需要手動修改,很麻煩,而且容易出錯。
Maven的資源過濾功能可以實現在構建時修改以“@xxx@”表示的屬性。資源過濾需要在pom.xml的<build>標籤下配置 resources:

<!-- profile對資源的操作 -->
<resources>
    <resource>
        <directory>src/main/resources</directory>
        <excludes>
            <exclude>application*.properties</exclude>
        </excludes>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
        <!-- 是否替換@xx@表示的maven properties屬性值 -->
        <filtering>true</filtering>
        <includes>
            <include>application.properties</include>
            <include>application-${profileActive}.properties</include>
        </includes>
    </resource>
</resources>

上面的第一個resource去掉了src/main/resources下的所有application*.properties檔案,“*”是萬用字元,表示此處有任何內容(沒有也可以)都匹配。
第二個resource新增了application.properties預設配置檔案和由profileActive屬性決定的相應profile配置檔案。並且filtering為true表示,會將檔案內容的“@xx@”替換為相應的變數(如檔案中的@profileActive@會替換為profileActive屬性值)。

3.4 Spring配置Profile

在application.properties預設配置檔案中配置:

spring.profiles.active              = @profileActive@

@profileActive@表示該屬性值會在maven構建時被替換掉。

3.5 構建

構建命令:

mvn clean package -Pdev

上面的命令會根據Maven Profile的 dev構建環境包,如果需要prod包,則把-P的引數替換成prod即可。
為了方便我會在每個專案下生成一個build.sh檔案,內容如下:

#!/bin/bash

profileActive=prod
if [ -n "$1" ]; then
    profileActive=$1
fi

mvn clean package -Dmaven.test.skip=true -P$profileActive

該指令碼接收一個引數,即打包對應的Profile。預設情況下如果不帶引數,會打包prod環境包。
需要注意的是,該命令跳過了測試。

4. 總結

完成了上面的五步,即可使專案根據你的構建引數的不同,打包出不同環境下執行的包。

  1. 第1步去掉了SpringBoot內嵌的tomcat和tomcat-jdbc。使得我們可以決定在什麼情況下使用何種容器執行我們的專案。
  2. 第2步配置了Maven構建Porfile,使得構建可根據我們的指令分發不同的包。
  3. 第3步配置了Maven資源過濾,不僅使得不同Profile下的資原始檔互不可見,且替換了資原始檔中以“@xx@”表示的屬性值。
  4. 第4步使Spring的Profile由Maven決策,這樣,我們就不用每次打包都修改Spring的Profile配置了。
  5. 第5步展示瞭如何執行不同Profile下的構建命令,並且使用了一個Shell指令碼方便我們執行構建和跳過測試(多數時候我們在構建專案時先測試,並不需要在構建時測試,測試和構建的解耦使得我們更專注。但同時,如果你忘記了前置測試,也可能會引發未察覺的測試問題)。

5. 參考

相關文章