maven構建的生命周期
maven是圍繞着構建生命周期這個核心概念為基礎的。maven里有3個內嵌的構建生命周期,default
,clean
和site
。 default
是處理你項目部署的;clean
生命周期是清楚你項目的;site
生命周期是生成你的項目文檔的。
default
生命周期由一下的階段組成:
validate
:驗證項目正確性和所有需要的信息是否正確;compile
:編譯項目源代碼;test
:用單元測試框架測試編譯后的代碼,測試階段不需要代碼打包和部署;package
:把編譯后的代碼按照發行版本的格式打包,例如:jar;verify
:檢驗集成測試的結果,確保質量可以接受;install
:安裝包到本地倉庫,為本地的其他項目依賴使用;deploy
:把最終的包復制到遠程倉庫,為其他的項目和開發者共享。
default
生命周期按照上面的順序執行。
使用下面的命令構建項目並發布到本地倉庫:
mvn install
上面的命令在執行install
之前,將執行默認的生命周期(validate
, compile
, package
等)。你只需要調用最后一個執行的命令即可。
下面的命令可以清除本地構建並重新打包發布到遠程倉庫:
mvn clean deploy
每一個構建階段都是由插件目標組成的,一個插件目標代表着一個特殊的工作。它可以被綁定到多個構建階段中,如果插件目標沒有綁定到構建階段中, 可以直接使用命令去執行。它們執行的順序取決於命令的順序。例如:
mvn clean dependency:copy-dependencies package
上例中,先執行clean
,再執行dependency:copy-dependencies
,最后執行package
。
pom文件
pom是Project Object Model的縮寫。它包含了項目的信息和詳細配置。
super pom是maven的默認pom,所有的pom都繼承super pom。super pom中的配置在你的pom中是有效的。
你能創建的最小pom的格式如下:
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany.app</groupId> <artifactId>my-app</artifactId> <version>1</version> </project>
每一個pom都需要配置groupId
, artifactId
, 和 version
。它代表這一個工件,工件的名稱格式如下:<groupId>:<artifactId>:<version>
。 上例中由於沒有指定打包的類型,將使用super pom的默認配置,所以它的類型是jar
。由於倉庫也沒有指定,將使用super pom中配置的倉庫, 我們可以看到super pom中配置了http://repo.maven.apache.org/maven2
。
super pom是項目繼承的一個例子,你也可以在項目中指定自己的父pom,例子如下:
. |-- my-module | `-- pom.xml `-- pom.xml
我們沿用上面的例子,項目的結構如上圖所示,根目錄下的pom是com.mycompany.app:my-app:1
的pom,my-module/pom.xml是com.mycompany.app:my-module:1
的pom。 my-module的pom如下:
<project> <parent> <groupId>com.mycompany.app</groupId> <artifactId>my-app</artifactId> <version>1</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany.app</groupId> <artifactId>my-module</artifactId> <version>1</version> </project>
它指定了父pom為my-app,並且指定自己的groupId,artifactId,version。如果你想要groupId,version沿用父pom的,可以將其省略掉,如下:
<project> <parent> <groupId>com.mycompany.app</groupId> <artifactId>my-app</artifactId> <version>1</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>my-module</artifactId> </project>
上面的例子中,父pom的位置在module的上一級目錄,如果父pom不在上一級目錄,該如何配置呢?
. |-- my-module | `-- pom.xml `-- parent `-- pom.xml
我們可以指定<relativePath>
元素,如下:
<project> <parent> <groupId>com.mycompany.app</groupId> <artifactId>my-app</artifactId> <version>1</version> <relativePath>../parent/pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>my-module</artifactId> </project>
推薦使用相對路徑指定父pom。
項目集合與項目的繼承非常像,不同點在於它在父pom中指定模塊,為了配置項目集合,你需要做兩點:
- 父pom的
packaging
改為pom
。 - 在父pom中指定它的模塊。
如果目錄結構為:
. |-- my-module | `-- pom.xml `-- pom.xml
父pom的配置如下:
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany.app</groupId> <artifactId>my-app</artifactId> <version>1</version> <packaging>pom</packaging> <modules> <module>my-module</module> </modules> </project>
如果目錄結構為:
. |-- my-module | `-- pom.xml `-- parent `-- pom.xml
父pom結構如下:
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany.app</groupId> <artifactId>my-app</artifactId> <version>1</version> <packaging>pom</packaging> <modules> <module>../my-module</module> </modules> </project>
profile
profile是環境配置,它配置了不同的環境下,項目中使用的值。profile可以定義的位置:
- 每個項目:pom文件;
- 每個用戶:
%USER_HOME%/.m2/settings.xml
中; - 全局配置:
${maven.home}/conf/settings.xml
中。
要使profile被觸發,通常是在maven打包編譯時指定profile-id。例如:
mvn clean install -P profile-1,profile-2
上面的例子將觸發兩個profile:profile-1
和profile-2
。
還有就是通過settings文件觸發,例如:
<settings> ... <activeProfiles> <activeProfile>profile-1</activeProfile> </activeProfiles> ... </settings>
一般情況下,這兩種方式就夠用了,還有其他的方式這里不做過多介紹。
配置profile的地方通常有兩個:settings和pom。settings因為時所有項目共同依賴的,所以在這里配置profile的元素時有限制的,可配置的元素 只能是:<repositories>
,<pluginRepositories>
和<properties>
。而在pom中可以配置所有的元素。
依賴機制
傳遞依賴
傳遞依賴的意思是,你依賴的包需要的依賴是不需要指定的,它們會自動的包含進來。maven會讀取你依賴包中的項目文件,通過項目文件找到依賴包所需要的依賴包。 當發生循環依賴的時候,會產生問題。
由於傳遞依賴,項目依賴包的圖會非常的巨大。正是因為這個原因,依賴的傳遞機制加入了額外的特性。
- 依賴調解——當依賴的多個版本同時出現時,決定哪個版本被使用。當前的maven版本使用的是“最近原則”。舉例說明,比如, A->B->C->D 2.0,並且A->E->D 1.0。最后,D1.0將被使用,因為D1.0離A是最近的。你可以在A中強制指定依賴D2.0。 在距離相同的情況下,最先被聲明的那個依賴被使用。
- 依賴管理——在項目中可以直接指定依賴的版本,如上例所示。
- 依賴范圍——下面會詳細介紹
- 排除依賴——如果A->B->C,在項目A中可以通過
exclusion
元素排除掉C。 - 選擇依賴——如果項目Y->Z,項目Y可以配置Z為可選依賴(通過optional),當項目X->Y時,X僅依賴Y,而不依賴Z,如果X想要依賴Z,必須指定依賴。
依賴范圍有6個可選項
compile
:默認的依賴范圍,它的依賴在項目的類路徑下都是可用的。這些依賴將傳播到依賴的工程。provided
:非常像compile
,標志着你希望JDK或者容器在運行時提供依賴。例如,你在構建web項目時,Servlet API和Java EE API的范圍設置成provided
, 因為在運行時,容器提供了這些類。runtime
:標志着這個依賴在編譯期是不需要的,在運行期需要。test
:標志着應用的正常使用是不需要這個依賴的,僅僅在測試時需要。system
:這個與provided
相似,除了那些你必須顯示提供的,包含它的jar。這個工件時可用的,不會在倉庫中尋找。import
:這個范圍僅支持在依賴類型是pom
,且在<dependencyManagement>
元素中。它將被<dependencyManagement>
中的具體的依賴所取代。
今天就先介紹到這里,如有疑問,歡迎在評論區留言。