一、Maven概述
1.1 為什麼要學習Maven?
Maven作為依賴管理工具,能夠管理規模龐大jar包。使用Maven後,依賴對應的Jar包能夠自動下載、方便、快捷且規範。
Maven作為構建管理工具。當我們使用 IDEA 進行開發時,構建是 IDEA 替我們做的。脫離IDEA環境執行構建操作,需要專門工具。
在這裡插入圖片描述
1.2 什麼是 Maven?
Maven一款專門為 Java 專案提供構建和依賴管理支援的工具
1.構建:
構建構建指的是使用Java原始碼、圖片、配置檔案等生產一個可以在伺服器上執行專案的過程
構建的過程包含以下主要環節:
清理:刪除上一次構建的結果,為下一次構建做好準備
編譯:Java 源程式編譯成 *.class 位元組碼檔案
測試:執行提前準備好的測試程式
報告:針對剛才測試的結果生成一個全面的資訊
打包
Java工程:jar包
Web工程:war包
安裝:把一個 Maven 工程經過打包操作生成的 jar 包或 war 包存入 Maven 倉庫
部署
部署 jar 包:把一個 jar 包部署到 Nexus 私服伺服器上
部署 war 包:藉助相關 Maven 外掛(例如 cargo),將 war 包部署到 Tomcat 伺服器上
2.依賴
如果 A 工程裡面用到了 B 工程的類、介面、配置檔案等等這樣的資源,那麼我們就可以說 A 依賴 B。
依賴管理中要解決的具體問題:
jar 包的下載:使用 Maven 之後,jar 包會從規範的遠端倉庫下載到本地
jar 包之間的依賴:透過依賴的傳遞性自動完成
jar 包之間的衝突:透過對依賴的配置進行調整,讓某些jar包不會被匯入
1.3 Maven的工作機制
在這裡插入圖片描述
二、Maven解壓和配置
2.1 Maven核心程式解壓和配置
下載地址:https://maven.apache.org/download.cgi
核心程式壓縮包:apache-maven-3.8.4-bin.zip,解壓到非中文、沒有空格的目錄
著重關注 Maven 的核心配置檔案:conf/settings.xml
1、指定Maven本地倉庫:
把localRepository標籤從註釋中拿出來配置本地地址,放jar包
2、配置阿里雲提供的映象倉庫:
將原有例子註釋掉
加入我們的配置
3、配置Maven工程的基礎JDK版本
預設配置使用的JDK版本是1.5
配置環境變數的規律:
XXX_HOME 通常指向的是 bin 目錄的上一級
PATH 指向的是 bin 目錄
配置MAVEN-HOME
配置PATH
三、使用Maven:命令列環境
3.1 根據座標建立Maven工程
1.Maven中的座標
使用三個『向量』在『Maven的倉庫』中唯一的定位到一個『jar』包。
groupId:公司或組織的 id
artifactId:一個專案或者是專案中的一個模組的 id
version:版本號
2.座標和倉庫中 jar 包的儲存路徑之間的對應關係
座標:
上面座標對應的 jar 包在 Maven 本地倉庫中的位置:
Maven本地倉庫根目錄\javax\servlet\servlet-api\2.5\servlet-api-2.5.jar
3.實驗操作:
本地建立工作空間,在工作空間目錄下開啟命令列視窗
執行 mvn archetype:generate 命令,根據提示指定座標
mvn archetype:generate 主命令 外掛:目標
調整pom.xml修改依賴的junit版本號4.12版本
4.解讀pom.xml
<!-- 在dependency標籤內使用具體的座標依賴我們需要的一個jar包 -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!-- scope標籤配置依賴的範圍 -->
<scope>test</scope>
</dependency>
POM:專案物件模型(類比DOM:文件物件模型),是模型化思想的具體體現。pom.xml 配置檔案就是 Maven 工程的核心配置檔案。其實學習 Maven 就是學這個檔案怎麼配置,各個配置有什麼用。
6.約定的目錄結構
在這裡插入圖片描述
約定目錄結構的意義:
Maven 為了讓構建過程能夠儘可能自動化完成,所以必須約定目錄結構的作用。例如:Maven 執行編譯操作,必須先去 Java 源程式目錄讀取 Java 原始碼,然後執行編譯,最後把編譯結果存放在 target 目錄
約定大於配置:
Maven 對於目錄結構這個問題,沒有采用配置的方式,而是基於約定。這樣會讓我們在開發過程中非常方便。如果每次建立 Maven 工程後,還需要針對各個目錄的位置進行詳細的配置,那肯定非常麻煩。
目前開發領域的技術發展趨勢就是:約定大於配置,配置大於編碼
3.2 在Maven工程中編寫程式碼和構建
在子目錄中分別編寫java程式和測試類程式
進入pom.xml所在的目錄,執行Maven的構建命令。構建相關命令必須進入所操作工程的pom.xml目錄
清理操作:mvn clean 刪除target目錄
編譯操作:
主程式編譯:mvn compile 編譯結果存放目錄:target/classes
測試程式編譯:mvn test-compile 編譯結果存放目錄:target/test-classes
測試操作:mvn test 測試的報告存放的目錄:target/surefire-reports
打包操作:mvn package 打包的結果——jar 包,存放的目錄:target
安裝操作:mvn install
安裝的效果是將本地構建過程中生成的 jar 包存入 Maven 本地倉庫。這個 jar 包在 Maven 倉庫中的路徑是根據它的座標生成的。另外還會將pom.xml轉換為XXX.pom檔案一起存入本地倉庫。
3.3 建立Maven版的Web工程
生成Web工程的命令,回到工作空間根目錄來操作:
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeVersion=1.4
生成的Web工程的目錄結構:
在這裡插入圖片描述
建立Servlet
main目錄下建立java目錄
在java目錄下建立Servlet類所在的包的目錄,在包下編寫Servlet類
在web.xml中註冊Servlet
在index.jsp頁面編寫超連結
配置對servlet-api.jar包的依賴
對於不知道詳細資訊的依賴可以到https://mvnrepository.com/網站查詢。使用關鍵詞搜尋,然後在搜尋結果列表中選擇適合的使用
找到的servlet-api 的依賴資訊:加入到pom.xml中
在pro2-maven-web工程的pom.xml檔案中,配置依賴
補充建立目錄:pro02-maven-web\src\test\java\com\zju\maven
確認web工程依賴了Junit
建立測試類
執行Maven命令
測試命令:mvn test 測試操作會提前自動編譯
打包命令:mvn package 依賴的java工程變成Web工程中WEB-INF/lib目錄下的jar包
在這裡插入圖片描述
檢視當前Web工程所依賴的jar包列表:mvn dependency:list
TIP
[INFO] The following files have been resolved:
[INFO] org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO] com.atguigu.maven:pro01-maven-java:jar:1.0-SNAPSHOT:compile
[INFO] junit:junit:jar:4.12:test
格式是:groupId:artifactId:打包方式:version:依賴的範圍,可以用來定位倉庫中的Jar包
以樹形結構檢視當前Web工程的依賴資訊:mvn dependency:tree
TIP
[INFO] com.atguigu.maven:pro02-maven-web:war:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.12:test
[INFO] | - org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
[INFO] - com.atguigu.maven:pro01-maven-java:jar:1.0-SNAPSHOT:compile
3.5 依賴的範圍
標籤的位置:dependencies/dependency/scope
標籤的可選值:compile/test/provided/system/runtime/import
①compile 和 test 對比
main目錄(空間) test目錄(空間) 開發過程(時間) 部署到伺服器(時間)
compile(預設) 有效 有效 有效 有效
test 無效 有效 有效 無效
②compile 和 provided 對比
main目錄(空間) test目錄(空間) 開發過程(時間) 部署到伺服器(時間)
compile 有效 有效 有效 有效
provided 有效 有效 有效 無效
③結論
compile:在專案實際實際執行時真正要用到的jar包
test:測試過程中用到的jar包,比如junit
provided:在開發過程中需要用到的“伺服器上的 jar 包”通常以 provided 範圍依賴進來。比如 servlet-api、jsp-api。而這個範圍的 jar 包之所以不參與部署、不放進 war 包,就是避免和伺服器上已有的同類 jar 包產生衝突,同時減輕伺服器的負擔。說白了就是:“伺服器上已經有了,你就別帶啦!
3.6 傳遞依賴性
依賴的原則:
在 A 依賴 B,B 依賴 C 的前提下,C 是否能夠傳遞到 A,取決於 B 依賴 C 時使用的依賴範圍
B 依賴 C 時使用 compile 範圍:可以傳遞
B 依賴 C 時使用 test 或 provided 範圍:不能傳遞,所以需要這樣的 jar 包時,就必須在需要的地方明確配置依賴才可以。
注意:依賴傳遞是透過本地倉庫的,因此要執行Install使本地倉庫有最新的
利用依賴的傳遞性可以透過僅管理頂層幾個jar包依賴達到匯入n多jar包的效果
3.7 依賴的排除
1.概念:
當 A 依賴 B,B 依賴 C 而且 C 可以傳遞到 A 的時候,A 不想要 C,需要在 A 裡面把 C 排除掉。而往往這種情況都是為了避免 jar 包之間的衝突。
配置依賴的排除就是為了阻止某些jar包的傳遞。因為這樣的jar包會和其他Jar包衝突。
在這裡插入圖片描述
2.配置方式:
pro02---->pro01----->Sringcore----->commoons-logging
目的:在 pro02-maven-web 工程中配置對 commons-logging 的排除:
作用
一個大型工程拆分為很多module,對每個module各自維護依賴資訊不易管理且整個專案使用的框架版本需要統一。透過在父工程中為整個專案維護依賴資訊的組合既保證了整個專案使用規範、準確版本的 jar 包;又能夠將以往的經驗沉澱下來,節約時間和精力。
實際意義
編寫一套符合要求、開發各種功能都能正常工作的依賴組合並不容易。如果公司裡已經有人總結了成熟的組合方案,那麼再開發新專案時,如果不使用原有的積累,而是重新摸索,會浪費大量的時間。為了提高效率,我們可以使用工程繼承的機制,讓成熟的依賴組合方案能夠保留下來。
在這裡插入圖片描述
1.建立父、子工程:
建立pro03-maven-parent,修改打包方式
打包方式為 pom 的 Maven 工程中不寫業務程式碼,它是專門管理其他 Maven 工程的工程
進入 pro03-maven-parent 工程的根目錄,然後執行mvn archetype:generate命令來建立模組工程
(自動生成)檢視父工程的pom.xml,modules標籤是聚合功能的配置
2.在父工程中配置依賴的統一管理:
關鍵點:可以省略版本號;可以有選擇性引用
<!-- 自定義標籤,維護Spring版本資料 -->
<zju.spring.version>4.3.6.RELEASE</zju.spring.version>
1.好處:
一鍵執行 Maven 命令:很多構建命令都可以在“總工程”中一鍵執行。
配置聚合之後,各個模組工程會在總工程中展示一個列表,讓專案中的各個模組一目瞭然
2.聚合的配置:
在總工程中配置 modules 即可:
工程間迴圈依賴:A依賴B;B依賴C;C又依賴A,那麼在構建時報錯
DANGER
[ERROR] [ERROR] The projects in the reactor contain a cyclic reference:
四、使用Maven:IDEA環境
4.1 建立Maven工程
1 建立父工程
new建立maven專案-----> 配置座標----->開啟自動匯入(右邊扳手圖示)
在這裡插入圖片描述
2.配置Maven資訊
每次建立 Project 後都需要設定 Maven 家目錄位置,否則 IDEA 將使用內建的 Maven 核心程式(不穩定)並使用預設的本地倉庫位置。
在這裡插入圖片描述
3.建立Java模組工程
新建maven模組,配置相關依賴
編寫相關java程式和測試程式
三種方式執行Maven命令:
方法一:IDEA右邊Maven導航欄,藉助圖形化介面直接執行
在這裡插入圖片描述
方法二:手動輸入,輸入一些組合指令
在這裡插入圖片描述
-D 表示後面要附加命令的引數,字母 D 和後面的引數是緊挨著的,中間沒有任何其它字元
maven.test.skip=true 表示在執行命令的過程中跳過測試
mvn clean install -Dmaven.test.skip=true
方法三:找到要執行的pom.xml,右鍵Open in terminal,在命令列輸入指令
4.建立Web模組工程
先按相同操作建立一個Java模組
修改當前模組的pom.xml中打包方式
進行Web設定
開啟Project Structure---->Feacts------>選中想設定為Web工程的模組
藉助IDEA生成web.xml xxxmodule\src\main\webapp\WEB-INF\web.xml
在這裡插入圖片描述
生成webapp目錄對應war包中WEB-INF目錄
設定資源目錄
在這裡插入圖片描述
配置Tomcat
在這裡插入圖片描述
4.2 Maven工程匯入
1.git clone結合IDEA從github遠端庫匯入專案
2.來自工程目錄
解壓到IDEA工作空間中,直接用IDEA開啟工程
4.3 Maven模組匯入
複製想要匯入的模組到自己的工程目錄下
在IDEA中執行匯入
Projet Stucture----->modules----->import Module----->選中貼上的模組----->選擇以Maven形式
匯入Web工程得重新進行Web設定
修改匯入module的pom.xml檔案,改成自己project的父工程座標
在這裡插入圖片描述
web工程打成war包後,pom.xml中的依賴會統一放在war包webapp目錄下的WEBINF下的lib目錄中
五、其他核心概念
5.1生命週期
為了讓構建過程自動化完成,Maven 設定了三個生命週期,生命週期中的每一個環節對應構建過程中的一個操作。
在任何一個生命週期內部,執行任何一個具體環節的操作,都是從本週期最初的位置開始執行,直到指定的地方。(本節記住這句話就行了,其他的都不需要記)
在這裡插入圖片描述
5.2 外掛和目標
1.外掛
Maven 的核心程式僅僅負責宏觀排程,不做具體工作。具體工作都是由 Maven 外掛完成的。例如:編譯就是由 maven-compiler-plugin-3.1.jar 外掛來執行的。
2.目標
一個外掛可以對應多個目標,而每一個目標都和生命週期中的某一個環節對應。
Default 生命週期中有 compile 和 test-compile 兩個和編譯相關的環節,這兩個環節對應 compile 和 test-compile 兩個目標,而這兩個目標都是由 maven-compiler-plugin-3.1.jar 外掛來執行的。
5.3 倉庫
本地倉庫:在當前電腦上,為電腦上所有 Maven 工程服務
遠端倉庫:需要聯網
區域網:我們自己搭建的 Maven 私服,例如使用 Nexus 技術。
Internet
中央倉庫
映象倉庫:內容和中央倉庫保持一致,但是能夠分擔中央倉庫的負載,同時讓使用者能夠就近訪問提高下載速度,例如:Nexus aliyun
建議:不要中央倉庫和阿里雲映象混用,否則 jar 包來源不純,彼此衝突。
專門搜尋 Maven 依賴資訊的網站:https://mvnrepository.com/
置開始執行,直到指定的地方。(本節記住這句話就行了,其他的都不需要記)**
[外鏈圖片轉存中…(img-uLXdPpSB-1648617732737)]
5.2 外掛和目標
1.外掛
Maven 的核心程式僅僅負責宏觀排程,不做具體工作。具體工作都是由 Maven 外掛完成的。例如:編譯就是由 maven-compiler-plugin-3.1.jar 外掛來執行的。
2.目標
一個外掛可以對應多個目標,而每一個目標都和生命週期中的某一個環節對應。
Default 生命週期中有 compile 和 test-compile 兩個和編譯相關的環節,這兩個環節對應 compile 和 test-compile 兩個目標,而這兩個目標都是由 maven-compiler-plugin-3.1.jar 外掛來執行的。
5.3 倉庫
本地倉庫:在當前電腦上,為電腦上所有 Maven 工程服務
遠端倉庫:需要聯網
區域網:我們自己搭建的 Maven 私服,例如使用 Nexus 技術。
Internet
中央倉庫
映象倉庫:內容和中央倉庫保持一致,但是能夠分擔中央倉庫的負載,同時讓使用者能夠就近訪問提高下載速度,例如:Nexus aliyun
建議:不要中央倉庫和阿里雲映象混用,否則 jar 包來源不純,彼此衝突。
專門搜尋 Maven 依賴資訊的網站:https://mvnrepository.com/