一、pom.xml文件
? 就像項目管理軟件 Make 的 MakeFile、Ant 的 build.xml 一樣,Maven 項目的核心是 pom.xml。POM( Project Object Model,項目對象模型 ) 定義了項目的基本信息,用于描述項目如何構建,聲明項目依賴,等等。
? 類似的軟件還有Gradle。
二、坐標
1、坐標的概念
? 在 Maven 中坐標是構件的唯一標識,Maven 坐標的元素包括 groupId、artifactId、version、packaging、classifier。上述5個元素中,groupId、artifactId、version 是必須定義的,被簡稱為“三維坐標”,packaging 是可選的 ( 默認為 jar )。
2、坐標的意義
? Maven世界擁有大量構建,我們需要找一個用來唯一標識一個構建的統一規范,即通過三維坐標找到具體的jar包。擁有了統一規范,就可以把查找工作交給機器。
3、坐標的含義
(1)groupId
??組織標識,一般為:公司網址的反寫+項目名
(2)artifactId
??項目名稱,一般為:項目名-模塊名
(3)version
??版本號,形式為0.0.1-SNAPSHOT:
- 第一個 0 表示大版本號,第二個 0 表示分支版本號,第三個 0 表示小版本號
- SNAPSHOT -- 快照版本,ALPHA -- 內側版本,BETA -- 公測版本,RELEASE -- 穩定版本,GA -- 正式發布
(4)packaging
? 打包的方式,如:pom,jar,maven-plugin,ejb,war,...
- jar
- war:帶有前端頁面的前端包
- pom:沒有代碼,只做依賴管理的pom包
(5)clissifier
? 用來幫助定義構件輸出的一些附屬構件。
4、自己項目的坐標
這是一個名為Hello的MavenJava項目,該項目的pom.xml如下圖:
其中:
<groupId>cn.tx.maven</groupId>
? ?項目的全球唯一標識符,通常使用全限定的包名區分該項目和其他項目。并且構建時生成的路徑也是由此生成,如cn.tx.maven生成的相對路徑為:/cn/tx/maven。
<artifactId>Hello</artifactId>
? 構件的標識符,它和groupId一起唯一標識一個構件。也就是說,兩個不同的項目不能擁有同樣的groupId和artifactId。
<version>0.0.1-SNAPSHOT</version>
? 項目當前版本,格式為:主版本.次版本.增量版本--限定版本號。
<packaging>jar</packaging>
? 項目產生的構件類型,例如jar、war、pom等。插件可以創建他們自己的構件類型,所以前面列的不是全部構建類型。?
5、第三方項目坐標
? 自己項目依賴包一般是從本地倉庫或者私服中獲取。
三、依賴?
1、依賴的意義
? 當編寫Java代碼時,我們總是需要一些庫,例如,做單元測試我們需要JUnit庫。對于更大的項目,我們可能需要創建自己的庫并在不同的部分使用它的項目。不同的項目需要不同版本的庫。 保持項目最新的庫JAR文件的正確版本不是一個容易的任務。
? 每個外部JAR可能還依賴于其他外部JAR文件等。以遞歸方式下載所有這些外部依賴JAR文件并確保下載正確的版本是一項巨大的任務。
? 當項目越來越大,我們將需要越來越多的外部依賴。
? Maven將下載它們并將它們放在您的本地Maven存儲庫中。
? 我們可以在POM文件中的dependencies元素內指定依賴關系。
2、依賴的使用
? 例如我們的項目需要進行單元測試,則需要使用到junit-4.9.jar包,使用maven引用該依賴的方式如下:
?屬性說明:
? 三維坐標:引用依賴包的三維坐標,用來定位該依賴包;
? <dependencies>?</dependencies> :表示一個包含所有依賴的集合;
? <dependency></dependency>:表示一個具體的依賴,可以是本地項目,也可以是第三方依賴;
? <scope></scope>:?控制該依賴包在什么情況下會被加到 classpath 中,即該依賴包什么時候生效。
3、第三方依賴的查找方法
? 我們在不確定所需引用的第三方依賴包的坐標時,通過maven的中央倉庫進行查找,網址:?https://mvnrepository.com/;
以mybatis舉例:
四、依賴范圍
? Maven項目在開發工程中有三套classpath
- 主代碼:main下面的都是主代碼在編譯的時候的依賴
- 測試代碼:test下是測試代碼編譯的時候的依賴
- 運行時:main代碼在運行的時候對包的依賴
? 依賴范圍的使用,通過在引用第三方依賴時的<scope></scope>標簽進行設置,例如:
? 上圖的junit,只在測試中使用,則選擇test即可,而默認情況為compile。
? scope共 6 種,包括:compile、provided、runtime、test、system、import。
- compile:編譯依賴范圍。默認使用此依賴范圍,其下的maven依賴,對于編譯,測試,運行classpath都有效。
- test:測試依賴范圍。只對測試classpath有效,編譯主代碼或運行項目時無法使用此依賴。典型例子如junit。
- provided:已提供依賴范圍。其對于編譯與測試classpath有效,運行時無效。如在web開發時,只有在編譯和測試時才用到servlet-api,將其設置為此范圍,在運行時servlet-api由web容器提供,無須依賴。并且在打war包時,此范圍的依賴不會打在WEB-INF/lib下。
- runtime:運行時依賴范圍。與provided相對,運行時classpath有效。典型例子如jdbc(編寫是接口規范運行是提供具體實現類需要jar包)。
五、依賴傳遞和可選依賴
1、依賴傳遞
應用場景:
第一直接依賴:??HelloFriend項目依賴Hello項目?
第二直接依賴:??MakeFriend項目依賴HelloFriend項目
MakeFriend項目只依賴了HelloFriend,但是也把Hello依賴了進來。
2、依賴范圍對傳遞依賴的影響
?傳遞依賴是會受到依賴范圍的影響的,具體來看結果如下:
3、依賴阻斷
我們使用
例如我們在HelloFriend項目里面的Hello依賴處添加該配置。
則makeFriend項目里面就不會再引入Hello的依賴
4、可選依賴
如果我們需要在依賴中明確的排除掉某一依賴,則可以使用exclusion屬性,排除掉引用的依賴,如圖:?
六、倉庫
1、倉庫的概念
在 Maven 的術語中,倉庫是一個位置(place)。
Maven 倉庫是項目中依賴的第三方庫,這個庫所在的位置叫做倉庫。
在 Maven 中,任何一個依賴、插件或者項目構建的輸出,都可以稱之為構件。
Maven 倉庫能幫助我們管理構件(主要是JAR),它就是放置所有JAR文件(WAR,ZIP,POM等等)的地方。
倉庫的類型有:
- 本地(local)
- 中央(central)
- 遠程(remote)
2、本地倉庫
Maven 的本地倉庫,在安裝 Maven 后并不會創建,它是在第一次執行 maven 命令的時候才被創建。
運行 Maven 的時候,Maven 所需要的任何構件都是直接從本地倉庫獲取的。如果本地倉庫沒有,它會首先嘗試從遠程倉庫下載構件至本地倉庫,然后再使用本地倉庫的構件。
默認情況下,不管Linux還是 Windows,每個用戶在自己的用戶目錄下都有一個路徑名為 .m2/respository/ 的倉庫目錄
Maven 本地倉庫默認被創建在 %USER_HOME% 目錄下。要修改默認位置,在 %Maven_HOME%\conf 目錄中的 Maven 的 settings.xml 文件中定義另一個路徑。
3、中央倉庫
Maven 中央倉庫是由 Maven 社區提供的倉庫,其中包含了大量常用的庫。
中央倉庫包含了絕大多數流行的開源Java構件,以及源碼、作者信息、SCM、信息、許可證信息等。一般來說,簡單的Java項目依賴的構件都可以在這里下載到。
中央倉庫的關鍵概念:
- 這個倉庫由 Maven 社區管理。
- 不需要配置。
- 需要通過網絡才能訪問。
4、依賴搜索順序
七、生命周期
1、生命周期的概念
Maven的生命周期是對所有的構建過程進行抽象和統一。Maven的生命周期是抽象的,這意味著生命周期本身不做任何實際的工作,生命周期只是定義了一系列的階段,并確定這些階段的執行順序。而在執行這些階段時,實際的工作還是由插件來完成的。這種思想與設計模式中的模板方法非常相似。
Maven有三套相互獨立的生命周期:
- Clean
-
- clean生命周期的目的是清理項目
-
- Default
-
- default生命周期的目的是構建項目
-
- site
-
- site生命周期的目的是建立項目站點。
-
2、完整生命周期
八、Maven的插件
九、Maven繼承和聚合
1、繼承的意義
? 繼承就是避免重復,maven的繼承也是這樣,它還有一個好處就是讓項目更加安全。比如我們在項目開發的過程中,可能多個模塊獨立開發,但是多個模塊可能依賴相同的公共模塊,比如說每個模塊都需要javaseo-utils,在編譯的時候,maven-compiler-plugin插件也要被引入,maven倉庫地址以及發布目錄都是相同的配置。我們可以使用Maven的繼承功能,把公共的配置信息寫到父模塊中,子模塊只要繼承了該父模塊,也會繼承父模塊的配置信息。
2、可繼承的pom元素
groupId?:項目組 ID ,項目坐標的核心元素;
version?:項目版本,項目坐標的核心元素;
description :項目的描述信息;
organization :項目的組織信息;
inceptionYear :項目的創始年份;
url :項目的 url 地址
develoers :項目的開發者信息;
contributors :項目的貢獻者信息;
distributionManagerment :項目的部署信息;
issueManagement :缺陷跟蹤系統信息;
ciManagement :項目的持續繼承信息;
scm :項目的版本控制信息;
mailingListserv :項目的郵件列表信息;
properties?:自定義的 Maven 屬性;
dependencies?:項目的依賴配置;
dependencyManagement?:醒目的依賴管理配置;
repositories :項目的倉庫配置;
build :包括項目的源碼目錄配置、輸出目錄配置、插件配置、插件管理配置等;
reporting :包括項目的報告輸出目錄配置、報告插件配置等。
3、IDEA實現Maven的繼承
以哈米音樂為例,所有的邏輯都在前臺(使用者)、后臺(管理員)、公共模塊和音頻圖片模塊
首先,創建父工程,父工程中不含任何代碼,僅做依賴管理,使得項目能夠產生繼承和聚合關系,因此父工程的創建是MavenJava就可以,并且目錄中僅有pom.xml,打包方式為pom。
在父工程下還有四個模塊
(1)公共模塊
公共模塊只負責操作數據庫,因此公共模塊的創建為MavenJava
因為公共模塊繼承了父工程,因此GroupId和Version會繼承父工程的邏輯,實現統一,不需要再另寫
hami_core的pom.xml如下:
此時,父工程的pom.xml也發生了變化,我們發現多了一個<modules></modules>標簽,而這個標簽就體現了Maven的聚合
(2)后臺模塊
后臺模塊是管理員管理模塊,因此后臺模塊的創建為MavenJavaWeb,創建成功之后,我們可以在后臺模塊的pom.xml中看到父工程、子項目項目名、打包方式、依賴等信息。
此時,我們發現父工程的pom.xml的<modules></modules>標簽中又多了一個<module></module>,這代表后臺模塊也成功被聚合在了一起。
同時,由于繼承關系,我們需要在后臺模塊的pom.xml中注入對公共模塊的依賴,因為后臺模塊和公共模塊已經成功被聚合在父工程里,所以這里我們注入依賴時,就不需要提前對公共模塊進行打包,并且在項目最終打包時,只需要在父工程的pom.xml點擊install,就可以把項目內的所有模塊打包完成。
(3)前臺模塊
(4)圖片服務器
此時,所有模塊都已創建完畢,在父工程的pom.xml中所有模塊都已被聚合
?<dep..ment>的作用:一般在父工程中只做依賴管理,不做應用,而是在子工程中進行實際應用
6、properties屬性的使用
通過 properties元素用戶可以定義一個或多個 maven 屬性,然后在 maven 的其他地方使用 ${屬性名稱} 的方式引用該屬性,這種做法的意義在于消除重復和統一管理。比如,需要在多個地方重復聲明同樣的 SpringFramework 版本,現在只需要在一個地方聲明就可以。?