一.問題發(fā)現(xiàn)
最近在學(xué)習(xí)Spring的過程中,遇到了這么一個問題:

原因圖上標(biāo)記得也很清楚,就是畫紅線的地方出了問題。
我在pom.xml中申明了一個web的依賴:spring-boot-starter-web。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Maven在進(jìn)行構(gòu)建的時候,會將web依賴的其它架包也連同架包web一同導(dǎo)入進(jìn)來。比如A依賴B,B依賴于C,也就是A -> B -> C。那么我導(dǎo)入A的時候,Maven會自動進(jìn)行檢測A是否依賴了其它架包,如果A依賴了其它架包,就會將A依賴的其它架包也導(dǎo)入進(jìn)來。對應(yīng)到這里,雖然我只是申明了需要導(dǎo)入A的架包,但是Maven會把B和C也導(dǎo)入進(jìn)來。
二.解決問題
回到這里,這個問題該怎么解決?
我在Stack Overflow上找到了一個回答,大意是說:
org.hibernate.validator:hibernate-validator:jar:6.0.11.Final這個包有些問題,建議更新到更高的版本。
于是,我導(dǎo)入了一個更高版本的org.hibernate.validator:hibernate-validator:jar。如下所示,我導(dǎo)入的為6.1.2版本。
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.2.Final</version>
</dependency>
可以從圖中看出,導(dǎo)入以后,以前有報錯的那個架包已經(jīng)變灰色了,顯然過去的6.0.11的架包應(yīng)該是不起作用了,是新的架包在起作用。

三.問題思考
我的思考
到這里,問題雖然解決了,但是引起了我的一些思考。同樣的架包,Maven在執(zhí)行的時候,究竟執(zhí)行哪一個,這里面有什么優(yōu)先級的順序嗎?
A -> B -> C(v1.0)。然后我在pom.xml中導(dǎo)入了A和C(v2.0)的依賴,那A究竟是執(zhí)行C(v1.0)還是執(zhí)行C(v2.0)?
由于前幾天剛剛在學(xué)CSS,對CSS的選擇器的印象比較深刻。在CSS里面,不加其它條件的情況下,ID選擇器的優(yōu)先級應(yīng)該是最高的,比如一個Class選擇器和ID選擇器都選擇到了某個元素,那肯定是執(zhí)行ID選擇器里面的樣式。為什么呢?因為ID選擇器更加精確!既然是要選擇,肯定要將范圍縮小到越小越好,這樣才能選擇。如果選擇的范圍很廣,那不就是全選了嘛,還需要選擇器做什么。ID選擇器能唯一定位到某個元素,而Class選擇器選擇的元素卻并非唯一的。
然后引申過來,我是這樣思考的。在這個項目中web ->hibernate-validator:jar(6.0.11)。但是我顯示的定義的只是表明我需要web架包,我再pom.xml中的定義如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
hibernate-validator:jar(6.0.11)只是因為執(zhí)行web架包需要用到,才迫不得已需要導(dǎo)入,而hibernate-validator在這里究竟是需要6.0.11的版本還是需要6.0.22的版本我不關(guān)心,Maven應(yīng)該也不關(guān)心,只要能用就行。
而當(dāng)我在pom.xml中申明了這個依賴的時候,如下所示:
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.2.Final</version>
</dependency>
這段程序表示了我顯示的告訴了Maven:
我需要hibernate-validator:jar這個架包,且我需要的是6.1.2.Final這個架包,其它的我不要,我就要這個。
然后Maven就接受了我的指令去下載6.1.2.Final版本的hibernate-validator的架包,并在我的項目的其它地方需要用到這個架包的時候,統(tǒng)統(tǒng)替換為我指定的這個版本。
當(dāng)然,上面只是我的思考,有對也有錯,下面是網(wǎng)上的一些回答
網(wǎng)上的答案
參考自:
pom文件中依賴的的優(yōu)先級順序
依賴最短路徑優(yōu)先原則:
一個項目依賴了兩個jar包,其中A -> B -> C ->X(1.0) , A -> D -> X(2.0)。由于X(2.0)路徑最短,所以項目使用的是X(2.0)。pom文件中申明順序優(yōu)先:
如果A -> B -> X(1.0) ,A -> C -> X(2.0) 這樣的路徑長度一樣怎么辦呢?這樣的情況下,maven會根據(jù)pom文件聲明的順序加載,如果先聲明了B,后聲明了C,那最后的依賴就會是X(1.0)。覆寫優(yōu)先
子pom內(nèi)聲明的優(yōu)先于父pom中的依賴。
四.總結(jié)
本文主要記錄了我在學(xué)習(xí)Sring的過程中遇到的一個小問題,并由此引發(fā)的一些關(guān)于Maven中依賴的優(yōu)先級的思考。上面我出現(xiàn)的那個問題的解決方法很多,除了上述將hibernate-validator:jar換成一個更高版本的架包以外,還可以把Spring boot的版本也換成一個更高版本的。原項目使用的是2.0.4.RELEASE的Spring boot,后來我替換為2.2.2.RELEASE,同樣也能解決問題。
本文若有不足,歡迎指正