在目前流行的SSM,SSH都採用Maven作爲項目構建工具,所以有必要 基於《Maven權威指南》 進行一次較系統的學習。
1、介紹Apache Maven
1.1 Maven較正式定義
Maven是一個項目管理工具,它包含了一個項目對象模型 (Project Object Model),一組標準集合,一個項目生命週期(Project Lifecycle),一個依賴管理系統(Dependency Management System),和用來運行定義在 生命週期階段(phase)中插件(plugin)目標(goal)的邏輯。 當你使用Maven的時候,你用一個明確定義的項目對象模型來描述你的項目,然後 Maven 可以應用橫切的邏輯, 這些邏輯來自一組共享的(或者自定義的)插件。
1.2 約定大於配置
• Maven 擁有約定,因爲你遵循了約定,它已經知道你的源代碼在哪裏。它把字節碼放到 target/classes ,然後在 target 生成一個 JAR 文件。
• Maven 是聲明式的。你需要做的只是創建一個 pom.xml 文件然後將源代碼放到默認的目錄。Maven 會幫你處理其它的事情。
• Maven 有一個生命週期,當你運行 mvn install 的時候被調用。這條命令告 訴 Maven 執行一系列的有序的步驟,直到到達你指定的生命週期。遍歷生命週期旅途中的一個影響就是,Maven 運行了許多默認的插件目標,這些目標完成了像編譯和創建一個 JAR 文件這樣的工作。
2、 項目對象模型(POM)
2.1、我們已經確定了POM是描述性和聲明性的,它不像Ant或者Make那樣提供顯式的指令,我們也注意到POM的概念不是特定於Java的。
2.2、屬性引用:一個POM可以通過一對大括弧和前面一個美元符號來包含 對屬性的引用 ${app.bu.version}
2.3、依賴範圍:項目依賴”簡要介紹了三種依賴範圍:compile,test,和provided
compile(編譯範圍) compile是默認的範圍;如果沒有提供一個範圍,那該依賴的範圍就是編譯範 圍。編譯範圍依賴在所有的classpath中可用,同時它們也會被打包。
provided(已提供範圍) provided依賴只有在當JDK或者一個容器已提供該依賴之後才使用。例如,如果 你開發了一個web應用,你可能在編譯classpath中需要可用的Servlet API來編 譯一個servlet,但是你不會想要在打包好的WAR中包含這個Servlet API;這個 Servlet API JAR由你的應用服務器或者servlet容器提供。已提供範圍的依賴在 編譯classpath(不是運行時)可用。它們不是傳遞性的,也不會被打包。
runtime(運行時範圍) runtime依賴在運行和測試系統的時候需要,但在編譯的時候不需要。比如,你可能在編譯的時候只需要JDBC API JAR,而只有在運行的時候才需要JDBC驅動實 現。
test(測試範圍) test範圍依賴 在一般的 編譯和運行時都不需要,它們只有在測試編譯和測試運 行階段可用
system(系統範圍) system範圍依賴與provided類似,但是你必須顯式的提供一個對於本地系統中 JAR文件的路徑。這麼做是爲了允許基於本地對象編譯,而這些對象是系統類庫 的一部分。這樣的構件應該是一直可用的,Maven也不會在倉庫中去尋找它。如 果你將一個依賴範圍設置成系統範圍,你必須同時提供一個systemPath元素。注意該範圍是不推薦使用的(你應該一直儘量去從公共或定製的Maven倉庫中引用 依賴)。
2.4、依賴版本界限
(, ) 不包含量詞 (3.1,3.5)大於3.1小於3.5; (,3.5)小於3.5
[, ] 包含量詞 (3.1, 3.5] 大於3.1小於等於3.5; [3.1,] 大於等於3.1
2.5、傳遞性依賴
你可以只依賴於一些包如Spring Framework,而不 用擔心Spring Framework的所有依賴,Maven幫你自動管理了。加上springboot裏的jar包集成了很多spring的其他東西,結合maven傳遞性依賴,自動管理依賴。只有在子項目沒有直接聲明一個版本的時候,父POM的dependencyManagement定義的版本纔會被使用。
2.6、多模塊項目關係
<project>
<groupId>org.sonatype.mavenbook</groupId>
<artifactId>top-group</artifactId>
...
<modules>
<module>sub-group</module>
<module>project-c</module>
</modules>
...
</project>
--
當Maven讀取top-group的POM的時候,它會檢查它的modules元素,看到top-group引用了 項目sub-group和project-c。之後Maven會在它們的每個子目錄中尋找pom.xml。Maven爲 每一個子模塊重複這個過程:它會讀取sub-group/pom.xml然後看到sub-group項目通過 如下的modules元素引用了兩個項目。
2.7、 多模塊 vs. 繼承:達到重用依賴的目的
繼承於一個父項目和被一個多模塊項目管理是有區別的。一個父項目是指它把所有的值 傳給它的子項目。一個多模塊項目只是說它管理一組子模塊,或者說一組子項目。多模塊關係從上層往下定義。當建立一個多模塊項目的時候,你告訴一個項目它的構建需要包含指定的模塊。多模塊構建用來將模塊聚集到一個單獨的構建中。父子關係是從葉節點往上定義的。父子關係更多的是處理一個特定項目的定義。當你給一個子項目關聯一 個父項目的時候,你告訴Maven該項目的POM起源於另一個項目。
注意:一個項目只能有一個父項目。
3、構建生命週期
3.1 、Maven基於構建生命週期的中心概念。這意味着構建和分發特定工件(項目)的過程被明確定義。對於構建項目的人員,這意味着只需要學習一小堆命令即可構建任何Maven項目,POM將確保他們獲得所需的結果。Maven中有三種標準的生命週期:清理(clean),默認(default)(有時候也稱爲構建),和站點(site)。在默認(default)的生命週期處理你的項目部署,將清潔(clean)的生命週期處理項目的清理,而站點(site)的生命週期處理你的項目站點文檔的創建,開源文檔會用到。
3.2 3個生命週期的構建階段都綁定了默認插件,可以在項目中重新定義覆蓋(最好就用默認的)。