java不同包中含有全限定類名相同的類時的加載順序

如果有兩個不同的jar包中含有兩個全限定類名完全相同的類,那麼如果我們程序中使用到了這個類,會加載哪一個呢,今天我們就來做個試驗看看。

爲了做試驗,我們建立如下三個module,其中main是一個springboot項目,其中引用了demo1和demo2兩個模塊。如下圖

 

demo1和demo2中都有一個com.demo.DemoClass類,如下:

 

然後我們在main類中寫一個接口,訪問com.demo.DemoClass中的info字段,如下。

 

好了,啓動項目,訪問/test接口,可以看到,我們加載到的是demo1中的DemoClass。

 

接下來我們做一點改變,把maven中的依賴換個順序,demo1放下面,如下

 

再次啓動,訪問/test,可以看到我們加載到的是demo2中的DemoClass。說明我們訪問到的類和在maven中的依賴順序有關。

 

以爲這就完了?no no no !

我們接着做試驗,這次我們把我們的springboot項目打成war包,部署到tomcat看一下。

如下圖是把我們的項目部署到tomcat,可以看到我們的demo1和demo2兩個依賴,啓動tomcat訪問一下/test,這裏就不截圖了,和上面結果圖差不多,但是結論不一樣,結論就是無論我們maven依賴順序如何,訪問到的始終是demo1中的DemoClass。

 

這裏我們再做個試驗,把demo1-1.0-SNAPSHOT.jar,重新命名爲demo3-1.0-SNAPSHOT.jar,注意此時demo3排在了demo2下面,這一點很重要(注意demo3-1.0-SNAPSHOT.jar中的info字段仍然是"demo1中的DemoClass"),此時我們再重啓tomcat訪問,結論是這次加載到的是demo2中的DemoClass。

通過以上試驗可以看出,springboot jar包方式運行時,加載類時是按照maven中的依賴順序進行加載的,如果已經加載過某個類,則後依賴的jar包中有全限定類名相同的類時是不會被加載到的。但是在tomcat中,加載類的順序是按照jar包在操作系統中的文件排序進行的(這裏的文件排序不確定一定是文件名,不同操作系統文件排序規則可能不一樣),在多個jar包中有全限定類名相同的類的情況下,jar文件排序靠前的會被優先加載到。

爲什麼springboot就能保證按maven中的順序加載呢?我們打開springboot打的jar包,可以看到jar包中有個classpath.idx,打開這個文件可以看到裏面明確定義了各jar包的加載順序,所以能夠按照我們在maven中定義順序來加載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章