MAVEN 使用
maven
是一款優秀的服務構建工具,基於約定優於配置原則,提供標準的服務構建流程。maven
的優點不僅限於服務構建,使用maven
能夠做到高效的依賴管理,並且提供有中央倉庫可以完成絕大多數依賴的下載使用。
maven
自身提供有豐富的外掛,可以在不使用額外外掛的條件下完成服務的編譯、測試、打包、部署等服務構建流程,即maven
對服務的構建過程是通過多個外掛完成的,且maven
已經自定義了外掛的行為。可以理解為每一個外掛都是對介面的實現,可以自定義外掛,以完成自定義功能,例如完成對不同程式語言的服務構建過程。不過相對於gradle
的自定義外掛行為,maven
的實現過程略微複雜。
IDEA
配置maven
工具
File > Other Settings > Default Settings
進入Default Settings
設定框

Build, Execution, Deployment > Build Tools > Maven
進入maven
工具配置

上圖中展示了三項配置,Maven home directory
指向maven
工具根目錄,User settings file
指向conf
下的settings.xml
檔案,表示使用全域性的settings.xml
檔案,Local repository
指向本地倉庫地址。
settings.xml
檔案用於記錄本地倉庫、遠端倉庫以及認證資訊等maven
工程使用的元素,該檔案有兩種級別,使用者級別和全域性級別,存放位置一般為${maven.home}/conf/settings.xml
和${user.home}/.m2/settings.xml
。Local repository
本地倉庫用於存放自動下載後的依賴檔案和安裝到本地的服務。
settings.xml
檔案
settings.xml
檔案起到的作用為全域性作用,該檔案中定義的行為一般作用於多個工程,或者所有工程。其中有幾個較為重要的元素:
-
localRepository
本地倉庫的地址,在maven
工程中依賴的構件,首先到本地倉庫進行查詢,查詢不到才會到遠端倉庫查詢。 -
servers
在工程中進行構件部署或者依賴下載時,新增的repositories,distributionManagement
元素中定義了伺服器的地址,登入伺服器需要的認證資訊,例如祕鑰或者使用者名稱密碼需要與工程分離,所以定義在該標籤中與工程進行關聯。 -
mirrors
當遠端倉庫的連線速度較慢時,或者使用私服進行依賴控制時,可以配置映象伺服器來替代某個或所有遠端伺服器。 -
profiles
提供多套配置,根據環境不同、指定的條件判斷結果,選擇使用某種配置。例如在某個profile
中配置遠端倉庫和外掛倉庫,根據使用的作業系統是windows
或者unix
,選擇性啟用不同的配置。 -
activeProfiles
手動啟用使用某一個profile
配置。
建立maven
工程
File > New > Project
建立maven
工程

此處填寫的為專案的座標,GroupId
表示公司或組織,ArtifactId
表示產品,Version
表示產品版本號。
使用這三個欄位形成一個座標,完成對此工程的表述。在maven
的世界中,對所有依賴的引用都是通過座標完成的,即使用GAV(GroupId,ArtifactId,Version)
進行定位。
pom.xml
檔案

上圖所示為工程根目錄下的pom.xml
檔案內容,modelVersion
表示當前POM
模型的版本,對於當前的maven 3
而言,元素值為4.0.0
,groupId,artifactId,version
則是前面提到過的工程座標。
POM(Project Object Model)
作為專案物件模型,用於描述工程資訊、依賴資訊,並且定義構建過程中的操作。該檔案為maven
構建服務流程中最重要的檔案,雖然預設情況下檔案內容很少,只描述了工程的座標資訊,那是因為一切構建操作都是按照約定進行執行的,即約定優於配置(Convention Over Configuration)
。
目錄結構

由上圖可知,maven
預設生成的原始碼目錄為src\main\java
,預設的資源目錄為src\main\resources
,預設的測試目錄為src\test\java
。如果此工程已經完成,直接進行編譯、測試等構建過程的話,則會直接到預設目錄執行編譯、測試活動。
該目錄結構屬於約定的一種內容,因為平時建立工程目錄時多按照該結構設計,所以在maven
中直接生成該目錄結構,避免了人工的操作。可以自定義原始碼和編譯後目錄,只需要在pom.xml
檔案中指定,則編譯構建服務時按照指定的目錄進行。
以原始碼目錄、測試目錄和資源目錄三種為例,可以指定源路徑以及編譯後目錄:
<build> <!--編譯服務後的目標生成目錄--> <directory>${basedir}\target</directory> <!--原始碼目錄和編譯後原始碼生成目錄--> <sourceDirectory>${basedir}\src\main\java</sourceDirectory> <outputDirectory>${build.directory}\classes</outputDirectory> <!--原始碼下資源路徑和編譯後資源生成路徑--> <resources> <resource> <directory>${basedir}\src\main\resources</directory> <targetPath>${build.directory}\classes</targetPath> </resource> </resources> <!--測試路徑和編譯後測試生成路徑--> <testSourceDirectory>${basedir}\src\test\java</testSourceDirectory> <testOutputDirectory>${build.directory}\test-classes</testOutputDirectory> </build>
<build>
標籤中自定義檔案路徑時,可以使用檔案系統的全路徑,也可以使用工程內部的變數進行定義。這裡的${basedir}
表示工程根目錄,${build.directory}
表示編譯服務後的目標生成目錄,即<directory>
標籤定義的目錄。
maven
工程內部存在許多可以使用的變數,以原始碼和測試為例:
${build.sourceDirectory}
: 原始碼檔案目錄
${build.outputDirectory}
: 原始碼編譯後目錄
${build.testSourceDirectory}
: 測試檔案目錄
${build.testOutputDirectory}
: 測試檔案編譯後目錄
服務構建
maven
工程的構建過程存在三個生命週期:clean
,default
和site
,每個生命週期存在多個階段。clean
生命週期的作用為清理工程編譯後生成資訊;site
生命週期用於為工程生成站點,可以通過瀏覽器檢視各項站點資訊;下面主要討論default
生命週期的作用,該生命週期包含多個階段,主要完成工作如下:
-
validate:
對工程資訊進行校驗,判斷是否缺失必要的檔案 -
compile:
編譯原始碼 -
test:
使用測試框架執行測試檔案 -
package:
對編譯後文件進行打包,生成jar
或war
等格式檔案 -
verify:
對整合測試結果進行校驗,判斷是否達到質量標準 -
install:
按照打包檔案到本地倉庫 -
deploy:
將打包檔案部署到遠端伺服器
在生命週期內,對指定階段的執行,會執行該階段前的所有階段,例如執行mvn test
命令,實際執行的階段有validate、compile、test
。
之前提到過,maven
的服務構建過程是通過外掛來完成的,即每個階段要執行的操作,都是通過外掛定義實現的。每個外掛可以定義多個goal
,所以並不是每個階段對應一個外掛,而是對應外掛的一個goal
。通過將生命週期的階段與外掛的goal
進行繫結,在使用過程中只需要宣告要執行的宣告週期階段,即可呼叫繫結的外掛goal
完成操作。例如執行mvn install
命令,實際執行的是install
生命週期階段繫結的外掛的goal
。

上圖中Profiles
表示使用到的配置,Lifecycle
列舉了常用的生命週期階段,Plugins
列舉了常用外掛及外掛的goal
,這裡並沒有顯示出階段與goal
的繫結關係。下面展示的是maven 3.6.0
版本中,打包型別為jar
時,default
生命週期中各階段與外掛goal
的繫結關係:
<component> <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role> <role-hint>jar</role-hint> <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation> <configuration> <lifecycles> <lifecycle> <id>default</id> <!-- START SNIPPET: jar-lifecycle --> <phases> <process-resources> org.apache.maven.plugins:maven-resources-plugin:2.6:resources </process-resources> <compile> org.apache.maven.plugins:maven-compiler-plugin:3.1:compile </compile> <process-test-resources> org.apache.maven.plugins:maven-resources-plugin:2.6:testResources </process-test-resources> <test-compile> org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile </test-compile> <test> org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test </test> <package> org.apache.maven.plugins:maven-jar-plugin:2.4:jar </package> <install> org.apache.maven.plugins:maven-install-plugin:2.4:install </install> <deploy> org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy </deploy> </phases> <!-- END SNIPPET: jar-lifecycle --> </lifecycle> </lifecycles> </configuration> </component>
由繫結關係可知,執行mvn install
命令時,實際執行的是mvn org.apache.maven.plugins:maven-install-plugin:2.4:install
,該命令格式為mvn groupId:artifactId:version:goal
。