一篇文章帶你了解Maven的坐標(biāo)概念以及依賴(lài)管理
1、什么是坐標(biāo)?
①、數(shù)學(xué)中的坐標(biāo)
在平面上,使用 X 、Y 兩個(gè)向量可以唯一的定位平面中的任何一個(gè)點(diǎn)
在空間中,使用 X、Y、Z 三個(gè)向量可以唯一的定位空間中的任意一個(gè)點(diǎn)
②、Maven 中的坐標(biāo)
俗稱(chēng) gav:使用下面三個(gè)向量子倉(cāng)庫(kù)中唯一定位一個(gè) Maven 工程
在項(xiàng)目中的 pom.xml 文件中,我們可以看到下面gav的定義:
1、groupid:公司或組織域名倒序
<groupid>com.ys.maven</groupid>
2、artifactid:模塊名,也是實(shí)際項(xiàng)目的名稱(chēng)
<artifactid>Maven_05</artifactid>
3、version:當(dāng)前項(xiàng)目的版本
<version>0.0.1-SNAPSHOT</version>
③、Maven 坐標(biāo)和倉(cāng)庫(kù),jar 包的關(guān)系
什么是倉(cāng)庫(kù),后面我們會(huì)詳細(xì)講解,現(xiàn)在你只需要知道是Maven 用來(lái)存放 jar 包的地方。
那么依照上面定義的 gav,我們執(zhí)行 mvn -install 命令,會(huì)出現(xiàn)什么情況呢?
首先進(jìn)入到我們第二篇博客 Maven 的安裝配置,通過(guò) settings.xml 文件配置的倉(cāng)庫(kù)目錄。
將我們上面配置的 gav 向量組合起來(lái)就是目錄:
com/ys/maven/Maven_05/0.0.1-SNAPSHOT/Maven_05-0.0.1-SNAPSHOT.jar
其次,我們觀察打出來(lái)的 jar 包:
Maven_05-0.0.1-SNAPSHOT.jar
也就是 artifactid-version.jar
2、什么是依賴(lài)?
什么是 依賴(lài)?相信有過(guò)一定開(kāi)發(fā)經(jīng)驗(yàn)的人知道,每當(dāng)我們需要使用某個(gè)框架時(shí),比如 SpringMVC,那么我們需要導(dǎo)入相應(yīng)的 jar 包,但是手動(dòng)導(dǎo)入包的時(shí)候,往往會(huì)漏掉幾個(gè) jar 包,那么在使用該框架的時(shí)候系統(tǒng)就會(huì)報(bào)錯(cuò)。那么我們就說(shuō)導(dǎo)入的包與未導(dǎo)入的包存在依賴(lài)關(guān)系。而使用 Maven,我們只需要在 pom.xml 文件中進(jìn)行相應(yīng)的配置,它就會(huì)幫助我們自動(dòng)管理 jar 包之間的依賴(lài)關(guān)系。那么它是怎么管理的呢,接下來(lái)我們會(huì)詳細(xì)講解。
3、依賴(lài)的詳細(xì)配置
我們以 Junit 為例,在 pom.xml 文件中進(jìn)行詳細(xì)而完整的配置。
<project> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <type>...</type> <scope>...</scope> <optional>...</optional> <exclusions> <exclusion> <groupId>...</groupId> <artifactId>...</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
①、dependencies
:一個(gè) pom.xml 文件中只能存在一個(gè)這樣的標(biāo)簽。用來(lái)管理依賴(lài)的總標(biāo)簽。
②、dependency:
包含在dependencies標(biāo)簽中,可以有無(wú)數(shù)個(gè),每一個(gè)表示一個(gè)依賴(lài)
③、groupId,artifactId
和version
:依賴(lài)的基本坐標(biāo),對(duì)于任何一個(gè)依賴(lài)來(lái)說(shuō),基本坐標(biāo)是最重要的,Maven根據(jù)坐標(biāo)才能找到需要的依賴(lài)。
④、type
:依賴(lài)的類(lèi)型,對(duì)應(yīng)于項(xiàng)目坐標(biāo)定義的packaging。大部分情況下,該元素不必聲明,其默認(rèn)值是jar。
⑤、scope
:依賴(lài)的范圍,默認(rèn)值是 compile。后面會(huì)進(jìn)行詳解。
⑥、optional
:標(biāo)記依賴(lài)是否可選。
⑦、exclusions
:用來(lái)排除傳遞性依賴(lài),后面會(huì)進(jìn)行詳細(xì)介紹。
4、依賴(lài)的范圍 scope
一般情況下,我們對(duì)前面三個(gè)依賴(lài)用的比較多。下面的主程序表示maven 目錄結(jié)構(gòu) src/main/java.測(cè)試程序目錄結(jié)構(gòu)為:src/test/java
1、compile 范圍依賴(lài)
對(duì)主程序是否有效:有效
對(duì)測(cè)試程序是否有效:有效
是否參與打包:參與
是否參與部署:參與
典型例子:log4j
2、test 范圍依賴(lài)
對(duì)主程序是否有效:無(wú)效
對(duì)測(cè)試程序是否有效:有效
是否參與打包:不參與
是否參與部署:不參與
典型例子:Junit
3、provided 范圍依賴(lài)
對(duì)主程序是否有效:有效
對(duì)測(cè)試程序是否有效:有效
是否參與打包:不參與
是否參與部署:不參與
典型例子:servlet-api.jar,一般在發(fā)布到 服務(wù)器中,比如 tomcat,服務(wù)器會(huì)自帶 servlet-api.jar 包,所以provided 范圍依賴(lài)只在編譯測(cè)試有效?! ?/p>
4、runtime 范圍依賴(lài):
在測(cè)試、運(yùn)行的時(shí)候依賴(lài),在編譯的時(shí)候不依賴(lài)。例如:JDBC驅(qū)動(dòng),項(xiàng)目代碼只需要jdk提供的jdbc接口,只有在執(zhí)行測(cè)試和運(yùn)行項(xiàng)目的時(shí)候才需要實(shí)現(xiàn)jdbc的功能。
接下來(lái)我們舉幾個(gè)例子在工程中實(shí)際去理解:
test 依賴(lài)和 compile 依賴(lài)的區(qū)別:
①、首先我們?cè)?pom.xml 文件中配置,Junit 的 test 依賴(lài)
②、我們?cè)谥鞒绦蛑腥?dǎo)入 Junit 的包,然后進(jìn)行 mvn -compile 編譯,很明顯,test 范圍的在主程序中無(wú)效,故編譯會(huì)報(bào)錯(cuò)。
我們?cè)?code>src/main/java 包下新建 MavenTest.java
,并導(dǎo)入 Junit 包
然后執(zhí)行 mvn -compile 操作,如下圖報(bào)錯(cuò)信息:
③、我們將 Junit 的依賴(lài)范圍改為 compile,然后執(zhí)行 mvn -compile
發(fā)現(xiàn) mvn -compile 沒(méi)有報(bào)錯(cuò)了。
5、依賴(lài)的傳遞
比如我們創(chuàng)建三個(gè)Maven 工程,maven-first,maven-second以及maven-third,而third依賴(lài)于second,second又依賴(lài)于first,那么我們說(shuō) second是 third 的第一直接依賴(lài),first是second的第二直接依賴(lài)。而first是third的間接依賴(lài)。
依賴(lài)之間的傳遞如下圖:第一列表示第一直接依賴(lài),第一行表示第二直接依賴(lài)
總結(jié):
1、當(dāng)?shù)诙蕾?lài)的范圍是compile的時(shí)候,傳遞性依賴(lài)的范圍與第一直接依賴(lài)的范圍一致。 2、當(dāng)?shù)诙苯右蕾?lài)的范圍是test的時(shí)候,依賴(lài)不會(huì)得以傳遞。 3、當(dāng)?shù)诙蕾?lài)的范圍是provided的時(shí)候,只傳遞第一直接依賴(lài)范圍也為provided的依賴(lài),且傳遞性依賴(lài)的范圍同樣為 provided; 4、當(dāng)?shù)诙苯右蕾?lài)的范圍是runtime的時(shí)候,傳遞性依賴(lài)的范圍與第一直接依賴(lài)的范圍一致,但compile例外,此時(shí)傳遞的依賴(lài)范圍為runtime;
我們這里舉個(gè)例子來(lái)看:
①、第二依賴(lài)范圍是 test
Maven_first
的pom.xml
文件如下:
然后Maven_second
依賴(lài)Maven_fisrt,Maven_third
依賴(lài)Maven-second,其pom.xml 文件如下:
Maven_second的 pom.xml
Maven_third的 pom.xml
我們發(fā)現(xiàn)在 Maven_third和 Maven_second 都沒(méi)有 Maven_first 引入的 Junit 包,正好符合上面總結(jié)的第二點(diǎn):當(dāng)?shù)诙苯右蕾?lài)的范圍是test的時(shí)候,依賴(lài)不會(huì)得以傳遞。
②、第二依賴(lài)范圍是 compile
如果我們將 Maven_first 的Junit 改為 compile,那么將會(huì)符合上面總結(jié)的第一點(diǎn):當(dāng)?shù)诙蕾?lài)的范圍是compile的時(shí)候,傳遞性依賴(lài)的范圍與第一直接依賴(lài)的范圍一致。
6、依賴(lài)的排除
如果我們?cè)诋?dāng)前工程中引入了一個(gè)依賴(lài)是 A,而 A 又依賴(lài)了 B,那么 Maven 會(huì)自動(dòng)將 A 依賴(lài)的 B 引入當(dāng)前工程,但是個(gè)別情況下 B 有可能是一個(gè)不穩(wěn)定版,或?qū)Ξ?dāng)前工程有不良影響。這時(shí)我們可以在引入 A 的時(shí)候?qū)?B 排除。
比如:我們?cè)贛aven_first 中添加 spring-core,maven
會(huì)自動(dòng)將 commons-logging
添加進(jìn)來(lái),那么由于Maven_second
是依賴(lài) Maven_first
的,那么 Maven_second
中將存在 spring-core
(自帶了commons-logging
),這時(shí)候我們不想要 commons-logging
,那該怎么辦呢?我們上面第二大點(diǎn)提到了:
exclusions:用來(lái)排除傳遞性依賴(lài)
Maven_first
的 pom.xml 文件
由于 Maven_second
依賴(lài) Maven_second
,故Maven_second
存在 spring-core
包
如何排除呢?我們?cè)?Maven_second
的 pom.xml 文件中添加如下代碼:
再次查看工程:Maven_second
的 commons-logging
已經(jīng)移除了
7、依賴(lài)的沖突
在maven中存在兩種沖突方式:一種是跨pom文件的沖突,一致是同一個(gè)pom文件中的沖突。
①、跨 pom 文件,路徑最短者優(yōu)先。比如我們?cè)?Maven_first 中的 Junit 是4.9版本的,Maven_second 中的 Junit 是4.8版本的,那么Maven_third 中的 Junit 將會(huì)是那個(gè)版本呢?
由上圖我們可以看出,由于 Maven_second 是 Maven_third 的直接依賴(lài),明顯相比于 Maven_first 路徑要短,所以 Maven_third 的 Junit 版本與 Maven_second 保持一致。
②、同一個(gè)pom.xml 文件,先申明者優(yōu)先。
看 Maven_second
8、可選依賴(lài)
Optional標(biāo)簽標(biāo)示該依賴(lài)是否可選,默認(rèn)是false。可以理解為,如果為true,則表示該依賴(lài)不會(huì)傳遞下去,如果為false,則會(huì)傳遞下去。
我們是在 Maven_second 的 pom 文件中設(shè)定 Junit 不可傳遞,那么Maven_third 工程中將不會(huì)有來(lái)自 Maven_second 的 Junit 的傳遞。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Spring Task 動(dòng)態(tài)修改任務(wù)執(zhí)行計(jì)劃cron方式
這篇文章主要介紹了Spring Task 動(dòng)態(tài)修改任務(wù)執(zhí)行計(jì)劃cron方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11SpringMVC與Mybatis集合實(shí)現(xiàn)調(diào)用存儲(chǔ)過(guò)程、事務(wù)控制實(shí)例
這篇文章主要介紹了SpringMVC與Mybatis集合實(shí)現(xiàn)調(diào)用存儲(chǔ)過(guò)程、事務(wù)控制實(shí)例,有需要的可以了解一下。2016-11-11老生常談設(shè)計(jì)模式之動(dòng)態(tài)代理
下面小編就為大家?guī)?lái)一篇老生常談設(shè)計(jì)模式之動(dòng)態(tài)代理。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06java 對(duì)象輸入輸出流讀寫(xiě)文件的操作實(shí)例
這篇文章主要介紹了java 對(duì)象輸入輸出流讀寫(xiě)文件的操作實(shí)例的相關(guān)資料,這里使用實(shí)現(xiàn)Serializable接口,需要的朋友可以參考下2017-07-07這么優(yōu)雅的Java ORM沒(méi)見(jiàn)過(guò)吧!
這篇文章主要介紹了Java ORM的相關(guān)資料,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2021-01-01Maven中dependency和plugins的繼承與約束
這篇文章主要介紹了Maven中dependency和plugins的繼承與約束,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12關(guān)于Spring?Boot項(xiàng)目的?log4j2?核彈漏洞問(wèn)題(一行代碼配置搞定)
相信昨天,很多小伙伴都因?yàn)長(zhǎng)og4j2的史詩(shī)級(jí)漏洞忙翻了吧,不過(guò)我看到群里發(fā)出來(lái)的各種修復(fù)方法,還真是不好看...所以這里也提一下Spring Boot用戶(hù)怎么修復(fù)最簡(jiǎn)單吧,對(duì)Spring Boot log4j2 核彈漏洞問(wèn)題感興趣的朋友參考下吧2021-12-12Java Spring MVC獲取請(qǐng)求數(shù)據(jù)詳解操作
Spring MVC 是 Spring 提供的一個(gè)基于 MVC 設(shè)計(jì)模式的輕量級(jí) Web 開(kāi)發(fā)框架,本質(zhì)上相當(dāng)于 Servlet,Spring MVC 角色劃分清晰,分工明細(xì)。由于 Spring MVC 本身就是 Spring 框架的一部分,可以說(shuō)和 Spring 框架是無(wú)縫集成2021-11-11