maven---靈活構建(一)

包含內容

  • maven屬性
  • 構建環境的差異
  • 資源過濾
  • Maven Profile
  • Web資源過濾
  • 在profile中激活集成測試
  • 小結

前言

  • 靈活構建:
  • 項目都會有開發環境、測試環境和產品環境,這些環境的數據庫庫配置不盡相同,那么項目構建的時候就需要能夠識別所在環境并使用正確的配置。
  • 項目開發了大量的集成測試,這些測試運行起來非常耗時,不適合在每次構建項目時都運行,因此需要一些手段能讓我們在特定的時候才激活這些集成測試。
  • maven如何實現靈活構建,內置了三大特性:
  • 屬性
  • Profile
  • 資源過濾

1.Maven屬性

  • maven中有6類屬性:
  • 內置屬性
  • POM屬性
  • 自定義屬性
  • Settings屬性
  • Java系統屬性
  • 環境變量屬性

1.1 內置屬性

  • 主要有兩個常用內置屬性
 ${basedir}表示項目根目錄,即包含pom.xml文件的目錄
  ${version}表示項目版本

1.2 POM屬性

  • 用戶可以使用該類屬性引用POM文件中對應元素的值。例如${project.artifactId}就對應了<project><artifactId>元素的值.
  • 常用的POM屬性包括:
${project.build.sourceDirectory}:項目的主源碼目錄,默認為src/main/java/。
${project.build.testSourceDirectory}:項目的測試源碼目錄,默認為src/test/java/。
${project.build.directory}:項目構建輸出目錄,默認為target/。
${project.outputDirectory}:項目的主代碼編譯輸出目錄,默認為target/classes/。
${project.testOutputDirectory}:項目測試代碼編譯輸出目錄,默認為target/test-classes/。
${project.groupId}:項目的groupId。
${project.artifactId}:項目的artifactId。
${project.version}:項目的version。
${project.build.finalName}:項目打包輸出文件的名稱,默認為${project.artifactId}-${project.version}。
<jdk.version>1.6</jdk.version>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  • 這些屬性都對應了一個POM元素,它們中的一些屬性的默認值是在超級POM中定義的。

1.3 自定義屬性

  • 用戶可以在POM的<properties>元素下自定義Maven屬性。例如:
<project>
    ...
     <properties>
          <my.prop>hello</my.prop>
     </properties>
     ...
</project>
  • 然后在POM中其他地方使用${my.prop}的時候會被替換成hello。

1.4 Settings屬性

  • 與POM屬性同理,用戶使用以settings.開頭的屬性引用settings.xml文件中XML元素的值,如常用的${settings.localRepository}指向用戶本地倉庫的地址。

1.5 Java系統屬性

  • 所有Java系統屬性都可以使用Maven屬性引用,例如${user.home}指向了用戶目錄。用戶可以使用mvn help:system查看所有的Java系統屬性。文章后面列出了查詢的結果。

1.6 環境變量屬性

  • 所有環境變量都可以使用以env.開頭的Maven屬性引用。例如${env.JAVA_HOME}指代了JAVA_HOME環境變量的值。用戶可以使用mvn help:system查看所有的Java系統屬性。

使用范例

  • 在一個多模塊項目中,模塊之間的依賴比較常見,這些模塊通常會使用同樣的groupId和version,這個時候就可以使用POM屬性。
<dependencies>
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>account-email</artifacId>
        <version>${project.version}</version>
    </denpendency>  
    <dependency>
        <groupId>${project.groupId}</groupId>
        <artifactId>account-persist</artifacId>
        <version>${project.version}</version>
    </denpendency>  
</dependencies>
  • 在配置插件的時候,同樣可以使用Maven屬性來方便地自定義插件行為。如:maven-surefire-plugin插件運行后默認的測試報告目錄為target/surefire-reports,這實際上就是${project.build.directory}/surefire-reports,查詢該插件文檔,發現該插件提供了reportsDirectory參數來配置測試報告目錄。因此如果想要改變測試報告目錄,如改成target/test-reports,就可以使用下面代碼:
 <plugin>
          <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-surefire-plugin</artifactId>
           <version>2.19</version>
           <configuration>
               <skip>false</skip>  <!-- 不跳過執行測試代碼 -->
               <reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
           </configuration> 
       </plugin> 

2. 構建環境的差異

  • 在不同的環境中,項目的源碼應該使用不同的方式進行構建。
    例如,我們在開發環境可能使用一套數據庫配置。
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/iqasdb?useUnicode=true&characterEncoding=UTF-8
jdbc.user=dev
jdbc.password=dev-pwd

在線上環境可能使用另外一套數據庫配置。

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://172.19.201.168:3306/iqasdb?useUnicode=true&characterEncoding=UTF-8
jdbc.user=test
jdbc.password=test-pwd
  • 相似的,對于緩存的配置、對于其他應用的RFC鏈接都可能在不同的生產環境下有不同的配置。
  • 那么對于不同環境的構建差異,要保證項目在不同的環境中都能正確的按照期望的來構建,作為一個構建 工具如何實現呢?
  • 實現思路:針對開發、測試等不同環境定義多組參數,在系統的配置文件中通過參數進行引用。在項目構建時對這些配置文件進行攔截,將參數使用值進行替換,但是因為對不同環境配置了多組參數,究竟使用哪一組進行替換需要通過一定的方式(命令行、settings文件、系統屬性等)來指明。這樣就可以實現不同環境進行特定的構建。
  • 為此需要做的事情大概涉及一下幾件事:1.為不同環境定義多組屬性。2.在系統資源文件中使用屬性名稱來配置,后期替換成真正需要的值。3.通過一種方式指明構建項目時使用哪一組屬性。4.對系統中使用屬性名稱進行配置的資源文件進行攔截,并將資源文件中的屬性名稱使用定義的屬性值進行替換。
  • 下面通過靈活配置數據庫信息進行具體說明。

3.資源過濾

3.1需求案例

  • 對于數據庫的配置來說,我們一般會在src/main/resources目錄下添加數據庫的配置文件jdbc.properties文件。連接數據庫使用的驅動類、URL、用戶名和密碼都可能發生變化,因此用Maven屬性取代它們。

3.2實現步驟

3.2.1. 在 jdbc.properties文件中使用屬性
jdbc.driverClass=${db.driver}
jdbc.jdbcUrl=${db.url}
jdbc.user=${db.username}
jdbc.password=${db.username}
  • 這里使用了4個Maven屬性,db.driver、db.url等,它們的命名是任意的,視情況而選擇合適名稱。
3.2.2.在POM中定義profile定義屬性

既然使用了Maven屬性,我們就需要在某個地方定義他們,前面介紹了自定義maven屬性,而上面這些屬性主要為了適應不同開發環境,所以maven提供了profile可以對不同屬性進行分類。在這里我們需要用到profile將其包裹起來,而且profile定義在POM中。

<project>
<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <db.driver>com.mysql.jdbc.Driver</db.driver>
            <db.url>jdbc:mysql://172.19.201.168:3306/iqasdb?useUnicode=true&characterEncoding=UTF-8</db.url>
            <db.username>dev</db.username>
            <db.password>dev-pwd</db.password>
        </properties>
    </profile>
</profiles>
</project>
3.3.3 配置maven-resources-plugin插件開啟資源過濾
  • 有了屬性定義,配置文件中也使用了這些屬性,但是這些屬性目前只能在POM中使用,如在POM使用{db.username}構建時其值會變成dev,但是如果放到src/main/resources/目錄下的文件中,如jdbc.properties中,構建時仍然是{db.username}。因此要讓Maven解析資源文件中的Maven屬性。
  • 資源文件的處理其實是maven-resources-plugin做的事情,它默認的行為只是將項目主資源文件復制到主代碼編譯輸出目錄中(target/classes),將測試資源文件復制到測試代碼編譯輸出目錄中,要讓該插件能夠解析資源文件中的Maven屬性,就需要開啟資源過濾,被過濾的文件Maven就會將其中的Maven屬性替換成對應的值。
  • 為主資源目錄和測試資源目錄開啟過濾。
<build>  
        <resources>  
            <resource>  
                <directory>${basedir}/src/main/resources</directory>  
                <filtering>true</filtering>  
            </resource>  
        </resources>  
        <testResources>  
            <testResource>  
                <directory>${basedir}/src/test/resources</directory>  
                <filtering>true</filtering>  
            </testResource>  
        </testResources>  

 </build>  
3.3.4 激活profile
  • 一切準備就緒,最后只要在命令行激活profile,maven就能夠在構建項目的時候使用profile中屬性值替換數據庫配置文件中的屬性引用。

  • 命令: mvn clean install -Pdev

  • -P參數表示在命令行激活一個profile。這里激活了id為dev的profile(多個id之間以逗號分隔)。構建完成后,輸出目錄中的數據庫配置就是開發環境的配置了:

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/iqasdb?useUnicode=true&characterEncoding=UTF-8
jdbc.user=dev
jdbc.password=dev-pwd

下一節內容

  • Maven Profile:profile更多的激活方式、不同的種類(不僅僅只有pom.xml可以定義哦,定義位置不同作用范圍也不一樣)、profile中可使用的元素等。

  • Web資源過濾:除了一般資源文件(src/main/resources)外,web還有包括了一種web資源文件(src/main/webapp),對于web資源文件的過濾又是怎么的呢?(首先處理web資源文件的插件不是maven-resources-plugin,所以配置resources時沒用的。)

  • 在profile中激活集成測試:一個項目中會有單元測試也會有集成測試,單元測試運行快,因此構建項目就快,集成測試運行比較耗時,所以如果不想每次構建都運行集成測試該怎么辦呢?


  • 通過mvn help:system查看的java系統屬性(其中系統環境變量沒有顯示粘貼出來)
===============================================================================
========================= Platform Properties Details =========================
===============================================================================

===============================================================================
System Properties
===============================================================================

java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=D:\Soft\Java\jdk1.8.0_65\jre\bin
java.vm.version=25.65-b01
maven.multiModuleProjectDirectory=C:\Users\dell
java.vm.vendor=Oracle Corporation
java.vendor.url=http://java.oracle.com/
guice.disable.misplaced.annotation.check=true
path.separator=;
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
file.encoding.pkg=sun.io
user.country=CN
user.script=
sun.java.launcher=SUN_STANDARD
sun.os.patch.level=Service Pack 1
java.vm.specification.name=Java Virtual Machine Specification
user.dir=C:\Users\dell
java.runtime.version=1.8.0_65-b17
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=D:\Soft\Java\jdk1.8.0_65\jre\lib\endorsed
os.arch=amd64
java.io.tmpdir=C:\Users\dell\AppData\Local\Temp\
line.separator=

java.vm.specification.vendor=Oracle Corporation
user.variant=
os.name=Windows 7
classworlds.conf=D:\Soft\maven\apache-maven-3.3.3\bin\m2.conf
sun.jnu.encoding=GBK
java.library.path=D:\Soft\Java\jdk1.8.0_65\bin;C:\Windows\Sun\Java\bin;C:\Window
s\system32;C:\Windows;D:\Soft\Spring-Boot-CLI\bin;D:\Soft\nexus-3.1.0-04-win64\n
exus-3.1.0-04\bin;D:\Soft\maven\apache-maven-3.3.3\bin;D:\Soft\Java\jdk1.8.0_65\
bin;D:\Soft\Java\jdk1.8.0_65\jre\bin;C:\ProgramData\Oracle\Java\javapath;C:\Prog
ram Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Window
s\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerS
hell\v1.0\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Fil
es\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(
R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Manage
ment Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engi
ne Components\IPT;D:\Soft\VanDyke Software\Clients\;D:\Soft\git\Git\bin;D:\Soft\
mysql\installationpath\MySQL Server 5.5\bin;.
java.specification.name=Java Platform API Specification
java.class.version=52.0
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
os.version=6.1
user.home=C:\Users\dell
user.timezone=Asia/Shanghai
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=GBK
java.specification.version=1.8
java.class.path=D:\Soft\maven\apache-maven-3.3.3\boot\plexus-classworlds-2.5.2.j
ar
user.name=dell
java.vm.specification.version=1.8
sun.java.command=org.codehaus.plexus.classworlds.launcher.Launcher help:system
java.home=D:\Soft\Java\jdk1.8.0_65\jre
sun.arch.data.model=64
user.language=zh
java.specification.vendor=Oracle Corporation
awt.toolkit=sun.awt.windows.WToolkit
java.vm.info=mixed mode
java.version=1.8.0_65
java.ext.dirs=D:\Soft\Java\jdk1.8.0_65\jre\lib\ext;C:\Windows\Sun\Java\lib\ext
sun.boot.class.path=D:\Soft\Java\jdk1.8.0_65\jre\lib\resources.jar;D:\Soft\Java\
jdk1.8.0_65\jre\lib\rt.jar;D:\Soft\Java\jdk1.8.0_65\jre\lib\sunrsasign.jar;D:\So
ft\Java\jdk1.8.0_65\jre\lib\jsse.jar;D:\Soft\Java\jdk1.8.0_65\jre\lib\jce.jar;D:
\Soft\Java\jdk1.8.0_65\jre\lib\charsets.jar;D:\Soft\Java\jdk1.8.0_65\jre\lib\jfr
.jar;D:\Soft\Java\jdk1.8.0_65\jre\classes
java.vendor=Oracle Corporation
sun.stderr.encoding=ms936
maven.home=D:\Soft\maven\apache-maven-3.3.3
file.separator=\
java.vendor.url.bug=http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding=UnicodeLittle
sun.cpu.endian=little
sun.stdout.encoding=ms936
sun.desktop=windows
sun.cpu.isalist=amd64

參考文章:Maven學習筆記(十一):靈活的構建

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容