包含內容
- 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}。因此要讓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學習筆記(十一):靈活的構建