1. maven中依賴范圍
首先需要知道,maven在編譯項目主代碼的時候需要使用一一套classpath。其次,maven在編譯和執(zhí)行測試的時候會使用另外一套classpath。運行項目又會使用另一套classpath。
依賴范圍就是用來控制依賴與這三種classpath(編譯classpath、測試classpath、運行classpath)的關系。maven有以下幾種依賴范圍:
- compile:編譯依賴范圍。如果沒有指定,就會默認使用該依賴范圍。使用次依賴范圍,對于編譯、測試和運行三種classpath都有效。典型的例子就是spring-core,在編譯、測試和運行的時候都需要使用此依賴。
- test:測試依賴范圍。使用次依賴范圍只對測試classpath有效,在編譯主代碼或者運行項目時無法使用此類依賴,典型例子:JUnit。
- provided:已提供依賴范圍。使用次依賴范圍,對于編譯和測試classpath有效。但在運行時無效。典型例子:servlet-api,編譯和測試項目的時候都需要該依賴,但是運行項目的時候,由于容器已經提供,就不需要maven重復的引入。
- runtime:運行時依賴范圍,使用此依賴范圍,對于測試和運行classpath都是有效,但在編譯時無效。典型例子:JDBC驅動,項目主代碼的編譯只需要JDK提供的JDBC接口,只有在執(zhí)行測試或者運行項目的時候才需要實現(xiàn)上述接口的具體JDBC驅動。
- system:系統(tǒng)依賴范圍。該依賴與三種classpath的關系和provided依賴范圍完全一致。但是,使用system范圍依賴時必須通過systemPath元素顯式地指定依賴文件的路徑。由于此類依賴不是通過maven倉庫解析的,而且往往與本機系統(tǒng)綁定,可能造成構建的不可移植,因此應該慎用。systemPath元素可以引用環(huán)境變量。
- import(Maven2.0.9及以上):導入依賴范圍,該依賴不會對三種classpath產生實際影響。
依賴范圍與classpath關系圖
| 依賴范圍 | 編譯classpath | 測試classpath | 運行classpath | 例子 |
|---|---|---|---|---|
| compile | Y | Y | Y | spring-core |
| test | N | Y | N | JUnit |
| provided | Y | Y | N | serlvet-api |
| runtime | N | N | Y | JDBC驅動實現(xiàn) |
| system | Y | Y | N | 本地的,maven倉庫之外的類庫文件 |
2.傳遞性依賴和依賴范圍
最左邊一行表示第一直接依賴范圍,最上面一行表示第二直接依賴范圍,中間交叉單元格則表示傳遞性依賴范圍。
| 第一依賴范圍列 | compile | test | provided | runtime |
|---|---|---|---|---|
| compile | compile | - | - | runtime |
| test | test | - | - | test |
| provided | provided | - | provided | provided |
| runtime | runtime | - | - | runtime |
3.依賴調解
maven引入的傳遞性依賴機制,一方面大大簡化和方便了依賴聲明,另一方面,大部分情況下我們只需要關心項目的直接依賴是什么,而不用考慮這些直接依賴會引入什么傳遞依賴。但是有時候,當傳遞依賴造成問題時,我們就需要清楚的知道該傳遞依賴是從哪條依賴路徑引入。
maven依賴調解原則:
- 路徑最近者優(yōu)先。
- 第一聲明者優(yōu)先
在依賴路勁長度相等的前提下,在POM中依賴聲明的順序決定了誰會被解析使用,順序最靠前的那個依賴優(yōu)勝。
4.maven生命周期
maven有三個內置生命周期:清理(clean)、默認(default)和站點(site)。clean生命周期處理項目的清理,default的生命周期處理項目部署,site生命周期處理項目站點文件創(chuàng)建。
- clean生命周期
| 事件 | 描述 |
|---|---|
| 預清理(pre-clean) | 執(zhí)行實際項目清理之前所需的流程 |
| 清理(clean) | 刪除以前構建生成的所有文件 |
| 清理后處理(post-clean) | 執(zhí)行完成項目清理所需的流程 |
- default生命周期
| 事件 | 描述 |
|---|---|
| 驗證(validate) | 驗證項目正確,所有必要信息可用 |
| 初始化(initialize) | 初始化構建狀態(tài),例如設置屬性或創(chuàng)建目錄 |
| 產生來源(generate-sources) | 生成包含在編譯中的任何源代碼 |
| 處理源代碼(process-sources) | 處理源代碼,例如過濾任何值 |
| 生成資源(generate-resources) | 生成資源文件 |
| 流程資源(process-resources) | 將資源復制并處理到目標目錄中,準備打包。 |
| 編譯(compile) | 編譯項目的源代碼。 |
| 工藝類(process-classes) | 從編譯后處理生成的文件,例如對Java類進行字節(jié)碼增強。 |
| 生成測試來源(generate-test-sources) | 生成包含在編譯中的任何測試源代碼。 |
| 流程測試來源(process-test-sources) | 處理測試源代碼,例如過濾任何值。 |
| 生成測試資源(generate-test-resources) | 創(chuàng)建測試資源。 |
| 流程測試資源(process-test-resources) | 將資源復制并處理到測試目標目錄中。 |
| 測試編譯(test-compile) | 將測試源代碼編譯到測試目標目錄中 |
| 流程檢驗類(process-test-classes) | 從測試編譯中處理生成的文件,例如對Java類進行字節(jié)碼增強。對于Maven 2.0.5及以上版本。 |
| 測試(test) | 使用合適的單元測試框架運行測試。這些測試不應該要求代碼被打包或部署。 |
| 制備包(prepare-package) | 在實際包裝之前,執(zhí)行必要的準備包裝的操作。這通常會導致打包的處理版本的包。(Maven 2.1及以上) |
| 打包(package) | 采取編譯的代碼,并以其可分發(fā)的格式(如JAR)進行打包。 |
| 預集成測試(pre-integration-test) | 在執(zhí)行集成測試之前執(zhí)行所需的操作。這可能涉及諸如設置所需環(huán)境等。 |
| 集成測試(integration-test) | 如果需要,可以將該包過程并部署到可以運行集成測試的環(huán)境中。 |
| 整合后的測試(post-integration-test) | 執(zhí)行集成測試后執(zhí)行所需的操作。這可能包括清理環(huán)境。 |
| 校驗(verify) | 運行任何檢查以驗證包裝是否有效并符合質量標準。 |
| 安裝(install) | 將軟件包安裝到本地存儲庫中,以作為本地其他項目的依賴關系。 |
| 部署(deploy) | 在集成或發(fā)布環(huán)境中完成,將最終軟件包復制到遠程存儲庫,以與其他開發(fā)人員和項目共享。 |
- site生命周期
| 事件 | 描述 |
|---|---|
| pre-site | 項目site生成前處理 |
| site | 生成項目site文檔 |
| post-site | 后處理 |
| site-deploy | 將生成的site文檔部署到指定的web服務器上 |