Current Classloader(目前類加載器)
每一個類都會使用自己的類加載器(即加載自身的類加載器) 來去加載其他類(指的是所依賴的類)
(PS: 說人話就是 用這個類的加載器去加載 它所依賴的類 例如它所繼承的類 )
(PPS :再例如 A 引用了B 那麼 A的類加載器 就會去加載B (前提是 B沒有被加載))
Context ClassLoader (線程上下文類加載器)
類Thread中的getContextClassLoader()與 setContextClassLoader(ClassLoader
cl) 分别用來擷取和設值上下文類加載器 如果沒有通過setContextClassLoader(ClassLoader
cl)進行設值的話,線程将繼承其父線程的上下文類加載器 JAVA
應用運作時的初始線程的上下文類加載器是系統類加載器(AppClassLoader)
線上程中運作的代碼可以通過該類加載器來加載類與資源
線程上下文類加載器的重要性
SPI (Service Provider Interface) 提供服務者
父classloader可以使用目前線程Thread.currentThread().getContextLoader()
所指定的ClassLoader加載的類 這就改變了父classloader
不能使用子classloader或是其他沒有直接父子關系的classLoader 加載的情況 即改變了雙親委托模型 (ps 用線程
getcontextloader 可以讓父加載器去加載子加載器的類 )
線程上下文類加載器就是目前線程的CurrentClassLoader
總結
在雙親委托模型下 , 類加載是由下至上的 , 即下層的加載器會委托上層進行加載 ,對于SPI來說
有些接口是JAVA核心庫所提供的而JAVA核心庫是由啟動類加載器來加載的
,而這些接口的實作是來自于不同的jar包(廠商的提供)JAVA的啟動類加載器是不會加載其他來源的jar包
這樣傳統的雙親委托模型就無法滿足SPI的要求 而通過給目前線程設定上下文類加載器就可以由設定的上下文類加載器來實作對接口實作類的加載(打破雙親委托模型限制)
(SPI 接口是由啟動類來加載的 而是實作類是由應用類加載器 來加載的)