JVM(四)打破雙親委派和SPI機制


前言:

我們都知道判斷兩個類是不是同一個,要根據類加載器和全限定名。這是為什么呢?為什么不同的類加載器加載同一個類是不同的呢?

答案就是,不同的類加載器所加載的類在方法區的存儲空間是不同的即InstanceKlass的不同。不同類加載器之間的空間是分隔開的。同一個類在一個類加載器中只會加載一次。

 雙親委派的弊端,無法做到不委派,也無法向下委派。

 

沙箱安全:

雖然JVM讓我們用一些方式打破雙親委派,但是對於系統的核心類庫JVM是會進行保護不讓篡改的。如果自己寫了和核心類庫相同的類,在運行的時候會出錯。

一:自定義類加載器打破雙親委派,不委派雙親

我們從上篇中有介紹classLoader.loadClass的時候會進行雙親委派進行加載,如果雙親都找不到指定類會調用findClass方法。

classLoader類中的loadClass有默認的實現就是雙親委派邏輯,findClass沒有默認的實現需要自定義類加載器來實現。

所以如果只是使用一個自定義類加載器而不打破雙親委派,只要繼承ClassLoader來重寫findClass。如果想打破雙親委派,也要重寫loadClass方法了,做到不委派。

二:SPI機制向下委派

SPI ,全稱為 Service Provider Interface,是一種服務發現機制。它通過在ClassPath路徑下的META-INF/services文件夾查找文件,自動加載文件里所定義的類。

這一機制為很多框架擴展提供了可能,比如在Dubbo、JDBC中都使用到了SPI機制。我們先通過一個很簡單的例子來看下它是怎么用的。SPI是實現向下委派的。

 

1:接口類模塊

就一個接口,讓其它模塊通過Maven引用。

 

 

 2:第一個接口實現類模塊

只有一個實現類,在resources下面增加META-INF/services文件夾,文件夾下面增加一個文本文件,文件名是實現的接口全路徑,文件里面的內容是實現的類的全路徑。

 

 

 

 

 3:第二個接口實現類模塊

 

 

 

 

 

 

 

 

 

 接下來我們開始使用SPI機制

 

 

 我們在pom中引入第一個實現類模塊:

上述main方法執行的結果就是對應實現類的執行結果。

 

當引入多個實現類的時候,都可以執行。

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM