Maven pom.xml與settings.xml詳解
pom.xml與settings.xml
pom.xml與setting.xml,可以說是Maven中最重要的兩個(gè)配置文件,決定了Maven的核心功能,雖然之前的文章零零碎碎有提到過pom.xml和settings.xml里面的內(nèi)容,但都是大略帶過,學(xué)習(xí)與研究地并不細(xì)致,本文的目的就是詳細(xì)研究下這兩個(gè)Maven重要的配置文件,從這兩個(gè)配置文件可以牽出非常多的Maven話題。
Maven坐標(biāo)
首先談一下為什么要使用Maven坐標(biāo)。
Maven世界擁有數(shù)量非常巨大的構(gòu)件,也就是平時(shí)使用的一些jar、war等文件,在Maven為這些構(gòu)件引入坐標(biāo)概念之前,我們無法使用任何一種方式來唯一標(biāo)識(shí)所有這些構(gòu)件。因此,如果需要使用Spring依賴,那么就去Spring官網(wǎng)尋找;如果需要使用log4j依賴,那么又去Apache官網(wǎng)尋找。又因?yàn)楦鱾€(gè)網(wǎng)站風(fēng)格迥異,大量時(shí)間花費(fèi)在了搜索和瀏覽網(wǎng)頁(yè)的工作上。沒有統(tǒng)一規(guī)范與法則,工作就無法自動(dòng)化,重復(fù)性的勞動(dòng)本來就應(yīng)該交給機(jī)器來做。
Maven定義了這樣一組規(guī)則:世界上任何一個(gè)構(gòu)件都可以使用Maven坐標(biāo)唯一標(biāo)識(shí),Maven坐標(biāo)元素包括groupId、artifactId、version、packaging、classifier,現(xiàn)在只要我們提供正確的元素坐標(biāo),Maven就能找到對(duì)應(yīng)的構(gòu)件。至于去哪里下載,Maven本身內(nèi)置了一個(gè)中央倉(cāng)庫(kù)的地址"http://repo1.maven.org/maven2",該中央倉(cāng)庫(kù)包含了世界上絕大部分流行的開源項(xiàng)目構(gòu)件,Mavne會(huì)在需要的時(shí)候去那里下載,當(dāng)然也可以配置自己的中央倉(cāng)庫(kù)地址,去自己的中央倉(cāng)庫(kù)下載構(gòu)件。
舉個(gè)例子,Spring的context:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.6.RELEASE</version> </dependency
看一下下屬的各個(gè)元素:
- groupId:定義當(dāng)前Maven項(xiàng)目隸屬的實(shí)際項(xiàng)目。由于Maven項(xiàng)目和實(shí)際項(xiàng)目未必是一對(duì)一的關(guān)系,比如SpringFramework這個(gè)實(shí)際項(xiàng)目可能對(duì)應(yīng)的Maven項(xiàng)目有很多,像core、context、expression等等,因此groupId不應(yīng)該對(duì)應(yīng)項(xiàng)目隸屬的公司或組織,否則artifact將很難定義
- artifactId:定義實(shí)際項(xiàng)目中的一個(gè)Maven模塊,推薦的做法是使用實(shí)際項(xiàng)目名稱作為artifactId的前綴,這樣會(huì)很方便去尋找實(shí)際構(gòu)件
- version:定義Maven項(xiàng)目當(dāng)前所處的版本,如上面的spring-context就是4.2.6的,RELEASE表示正式發(fā)行版本
- packing:定義Maven項(xiàng)目的打包方式,這項(xiàng)不是必須的,沒列出來,不定義默認(rèn)就是jar的打包方式
- classifier:幫助定義構(gòu)件輸出的一些附屬構(gòu)件,比如xxx-javadoc.jar、xxx-sources.jar,附屬構(gòu)件與主構(gòu)件對(duì)應(yīng),這項(xiàng)是不能直接定義的
Maven坐標(biāo)的概念大致上就是這樣,理解Maven坐標(biāo),是理解Maven很重要的一步。
傳遞性依賴
什么是傳遞性依賴,以Spring舉一個(gè)例子。使用Spring的時(shí)候會(huì)依賴于其他開源的類庫(kù),此時(shí)有兩種做法:
1、下載一個(gè)很大的.zip包,里面包含了所有Spring的jar,但是這么做往往就引入了許多不必要的依賴
2、只下載spring相關(guān)的.zip包,不包含依賴,實(shí)際使用的時(shí)候根據(jù)出錯(cuò)信息,加入需要的其他依賴
顯然這兩種做法都非常麻煩,Maven的傳遞性依賴機(jī)制很好地解決了這一問題。打開spring-core-4.1.0.RELEASE的pom.xml,我截取一段關(guān)鍵部分:
<dependencies> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.9</version> <scope>compile</scope> <optional>true</optional> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.3</version> <scope>compile</scope> </dependency> ... </dependencies>
比如A項(xiàng)目依賴了spring-core,spring-core又依賴了commons-codec和commons-logging,那么commons-codec和commons-logging就是A項(xiàng)目的一個(gè)傳遞性依賴。有了傳遞性依賴機(jī)制,在使用spring-core的時(shí)候就不用去考慮它依賴了什么,也不用擔(dān)心引入多余的依賴,Maven會(huì)解析各個(gè)直接依賴的POM,將那些必要的間接依賴,以傳遞性依賴的形式引入到當(dāng)前的項(xiàng)目中去。
有了傳遞性依賴機(jī)制,一方面大大簡(jiǎn)化和方便了依賴聲明,另一方面在大部分情況下我們只需要關(guān)心項(xiàng)目的直接依賴是什么而不用考慮這些直接依賴會(huì)引入什么傳遞性依賴,不過有時(shí)候傳遞性依賴也會(huì)有一些問題,此時(shí)我們就需要清除地知道該傳遞性依賴是從哪條路徑引入的,這就叫依賴調(diào)解,依賴調(diào)解主要有兩點(diǎn)原則:
1、A->B->C->X(1.0),A->D->X(2.0),此時(shí)兩條依賴路徑上有兩個(gè)版本的X,此時(shí)遵循路徑最近者優(yōu)先,因此X(2.0)將被解析使用
2、A->B->Y(1.0),A->C->Y(2.0),Y(1.0)和Y(2.0)的依賴長(zhǎng)度是一樣的,從Maven2.0.9開始,此時(shí)遵循第一聲明者優(yōu)先,即順序最靠前的那個(gè)依賴優(yōu)先
排除依賴
傳遞性依賴會(huì)給項(xiàng)目隱式地引入很多依賴,這極大地簡(jiǎn)化了項(xiàng)目依賴的管理,但是有時(shí)候這種特性也會(huì)帶來問題。比如有種情況:
當(dāng)前項(xiàng)目依賴A,A由于某些原因依賴了另外一個(gè)類庫(kù)的SNAPSHOT版本,那么這個(gè)SNAPSHOT就會(huì)成為當(dāng)前項(xiàng)目的傳遞性依賴,二SNAPSHOT的不穩(wěn)定性將直接影響到當(dāng)前的項(xiàng)目,此時(shí)就需要排除該SNAPSHOT,并且在當(dāng)前項(xiàng)目中聲明該類庫(kù)的某個(gè)正式發(fā)布的版本
排除依賴很簡(jiǎn)單,看一下寫法:
<dependency> <groupId>com.alibaba.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>3.2.7</version> <exclusions> <exclusion> <groupId>apache-lang</groupId> <artifactId>commons-lang</artifactId> </exclusion> </exclusions> </dependency>
這里我引入了rocketmq的依賴,但是我不想依賴rocketmq里面的apache-lang,而想要自己引入依賴,所以我就把a(bǔ)pache-lang給排除了。
這里需要注意的是,聲明exclusion的時(shí)候只需要groupId和artifactId即可,而不需要version元素,這是因?yàn)橹恍枰猤roupId和artifactId就能唯一定位依賴圖中的某個(gè)依賴。換句話說,Maven解析后的依賴中,不可能出現(xiàn)groupId和artifactId相同,但是version不同的兩個(gè)依賴。
settings.xml
settings.xml里面是Maven的基本配置,元素比較多,逐一看一下
1、proxy
proxy表示Maven的代理,看一下寫法:
<proxies> <proxy> <id>optional</id> <active>true</active> <protocol>http</protocol> <username>proxyuser</username> <password>proxypass</password> <host>proxy.host.net</host> <port>80</port> <nonProxyHosts>local.net|some.host.com</nonProxyHosts> </proxy> </proxies>
需要proxy是因?yàn)楹芏鄷r(shí)候你所在的公司基于安全因素考慮,要求你使用通過安全認(rèn)證的代理訪問因特網(wǎng)。這種情況下,就需要為Maven配置HTTP代理,才能讓它正常訪問外部倉(cāng)庫(kù),以下載所需要的資源。proxies下可以配置多個(gè)proxy元素,如果聲明了多個(gè)proxy元素,則默認(rèn)情況下第一個(gè)被激活的proxy會(huì)生效。active為true表示激活該代理,protocol表示使用的代理協(xié)議,當(dāng)然最重要的是指定正確的主機(jī)名(host)和端口(port),如果代理服務(wù)器需要認(rèn)證則配置username和password,nonProxyHost元素表示指定哪些主機(jī)名不需要代理,可以用"|"分隔多個(gè)主機(jī)名,也支持通配符"*"。
2、repository
repository表示Maven的中央倉(cāng)庫(kù),因?yàn)楸M管默認(rèn)的遠(yuǎn)程倉(cāng)庫(kù)中的構(gòu)件非常龐大,但是總歸會(huì)有不滿足我們需求的時(shí)候,這時(shí)候就要用到別的中央倉(cāng)庫(kù)了??匆幌聦懛ǎ?/p>
<repository> <id>public</id> <name>local private nexus</name> <url>http://192.168.1.6:8081/nexus/content/groups/public</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository>
可以聲明多個(gè)repository。id必須是唯一的,尤其注意,Maven自帶的中央倉(cāng)庫(kù)使用的id為central,如果其他倉(cāng)庫(kù)聲明也用該id,就會(huì)覆蓋中央倉(cāng)庫(kù)的配置。releases和snapshots比較重要,前者表示開啟倉(cāng)庫(kù)的發(fā)布版本下載支持,后者表示關(guān)閉倉(cāng)庫(kù)的快照版本下載支持,這樣一來,Maven就會(huì)去倉(cāng)庫(kù)下載發(fā)布版本的構(gòu)件而不會(huì)下載快照版本的構(gòu)件了。
3、server
大部分遠(yuǎn)程倉(cāng)庫(kù)無須認(rèn)證就可以訪問,但是有時(shí)候處于安全方面的因素考慮,需要提供認(rèn)證信息才能訪問一些遠(yuǎn)程倉(cāng)庫(kù),處于安全考慮,認(rèn)證信息一般只放在settings.xml中,server就是認(rèn)證元素??匆幌屡渲茫?/p>
<server> <id>nexus-releases</id> <username>deployment</username> <password>deployment</password> </server>
這里的關(guān)鍵是id,這個(gè)id必須與需要認(rèn)證的repositiry元素的id完全一致才行,換句話說,正式這個(gè)id將認(rèn)證信息和倉(cāng)庫(kù)配置聯(lián)系在了一起。
4、mirror
如果倉(cāng)庫(kù)X可以提供倉(cāng)庫(kù)Y存儲(chǔ)的所有內(nèi)容,那么就可以認(rèn)為倉(cāng)庫(kù)X是倉(cāng)庫(kù)Y的一個(gè)鏡像(mirror),換句話說,任何一個(gè)可以從Y中獲取到的構(gòu)件夠可以從X中獲取到。舉個(gè)例子,"http://maven.net.cn/content/groups/public/"是中央倉(cāng)庫(kù)"http://repo1.maven.org/maven2/"在中國(guó)的鏡像,由于地理位置的因素,該鏡像往往能夠提供比中央倉(cāng)庫(kù)更快的服務(wù),這就是為什么要使用mirror的原因。
看一下mirror的配置:
<mirror> <id>nexus</id> <name>internal nexus repository</name> <url>http://192.168.1.6:8081/nexus/content/groups/public</url> <mirrorOf>*</mirrorOf> </mirror>
該例子中,mirrof為*,表示該配置為所有中央倉(cāng)庫(kù)的鏡像,任何對(duì)于中央倉(cāng)庫(kù)的請(qǐng)求都會(huì)轉(zhuǎn)至該鏡像。另外三個(gè)元素id、name、url與一般倉(cāng)庫(kù)配置無異,表示該鏡像倉(cāng)庫(kù)的唯一標(biāo)識(shí)符、名稱以及地址。類似的,如果該鏡像需要認(rèn)證,也可以基于該id配置倉(cāng)庫(kù)認(rèn)證。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
長(zhǎng)度最小的子數(shù)組題目詳解(Java版)
這篇文章主要給大家介紹了關(guān)于長(zhǎng)度最小的子數(shù)組(Java版)的相關(guān)資料,這到題來自力扣,通過學(xué)習(xí)本文對(duì)大家理解這道題目有很大的幫助,需要的朋友可以參考下2023-12-12SpringBoot文件上傳控制及Java 獲取和判斷文件頭信息
這篇文章主要介紹了SpringBoot文件上傳控制的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-12-12springboot + mybatis配置多數(shù)據(jù)源示例
本篇文章主要介紹了springboot + mybatis配置多數(shù)據(jù)源示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03File.createTempFile創(chuàng)建臨時(shí)文件的示例詳解
這篇文章主要介紹了File.createTempFile創(chuàng)建臨時(shí)文件的示例詳解,在默認(rèn)臨時(shí)文件目錄中創(chuàng)建一個(gè)空文件,使用給定前綴和后綴生成其名稱。 如果感興趣來了解一下2020-07-07解讀Java和JavaScript區(qū)別與聯(lián)系
這篇文章主要介紹了解讀Java和JavaScript區(qū)別與聯(lián)系,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02關(guān)于Spring?Boot項(xiàng)目的?log4j2?核彈漏洞問題(一行代碼配置搞定)
相信昨天,很多小伙伴都因?yàn)長(zhǎng)og4j2的史詩(shī)級(jí)漏洞忙翻了吧,不過我看到群里發(fā)出來的各種修復(fù)方法,還真是不好看...所以這里也提一下Spring Boot用戶怎么修復(fù)最簡(jiǎn)單吧,對(duì)Spring Boot log4j2 核彈漏洞問題感興趣的朋友參考下吧2021-12-12logback?OutputStreamAppender高效日志輸出源碼解析
這篇文章主要介紹了為大家logback?OutputStreamAppender日志輸出效率提升示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10解決springboot中配置過濾器以及可能出現(xiàn)的問題
這篇文章主要介紹了解決springboot中配置過濾器以及可能出現(xiàn)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09Spring AOP如何在注解上使用SPEL表達(dá)式注入對(duì)象
這篇文章主要介紹了Spring AOP如何在注解上使用SPEL表達(dá)式注入對(duì)象,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02spring boot + mybatis實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于spring boot + mybatis實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-10-10