Spring IOC 容器為什麼不使用 Class.forName 載入類

業餘草發表於2019-02-23

點選上方“業餘草”,選擇“置頂公眾號”

第一時間獲取技術乾貨和業界資訊!

 

640?wx_fmt=png

很多人看過 Spring 的原始碼,但是他們都是為了看原始碼而看!並沒有讀懂 Spring 的設計思想,也沒有思考過為什麼要這樣設計!

我在這篇文章《程式設計師如何閱讀原始碼?大牛是如果形成的?》中,已經寫到了如何閱讀原始碼。而我的同事按照上面的步驟並結合自身的情況,再過去的幾個月看了不少的原始碼。最終今年破格加薪 2K !

那麼接下來我呀說的是,有哪些是你在看原始碼的過程中並沒有注意的細節和內容。比如,今天我們要學習的Spring IOC 容器為什麼不使用 Class.forName 載入類,而是使用 ClassLoader!

640

雖然 Class.forName() 和 ClassLoader 都可用來對類進行載入,但是它們還是有些區別的。為了說明它們,我們來看看 JVM 載入類的步驟是什麼!

640?wx_fmt=png

640

清楚上面這個之後,再要想搞明白 Spring Ioc中為什麼使用 Classloader,而不是 Class.forName,還得從它們的區別說起。我們先來看看如果使用 Class.forName 會發生什麼!

先建立一個測試類。

640?wx_fmt=png

上面的程式碼中, Class.forName("com.xttblog.Xttblog") 的呼叫會觸發 Xttblog 的靜態程式碼塊的執行, 而 ClassLoader.getSystemClassLoader().loadClass("com.xttblog.Xttblog") 並不會。

呼叫 Class.forName 其實相當於呼叫了 Class.forName(className, true, currentLoader), 這個方法的第二個參數列示是否需要初始化類。原始碼中設定為 true, 因此 Class.forName 獲取到 Class 物件時, 會自動對類進行初始化的。並且 Class.forName 載入類的 ClassLoader 和呼叫 Class.forName 所在的類的 ClassLoader 相同。上面的程式碼中, Class.forName("com.xttblog.Xttblog") 的呼叫會觸發 Xttblog 的靜態程式碼塊的執行, 而 ClassLoader.getSystemClassLoader().loadClass("com.xttblog.Xttblog") 並不會。

我們知道 Spring 的 IOC 中有一個懶載入(延遲載入),如果你使用了 Class.forName,那麼懶載入這個功能就無法實現了。Spring IoC 為了加快初始化速度,因此大量使用了延時載入技術。而使用 classloader 不需要執行類中的初始化程式碼,可以加快載入速度,把類的初始化工作留到實際使用到這個類的時候。

所以,Spring IOC 容器並沒有採用 Class.forName 來載入類。

原文連結:https://www.xttblog.com/?p=3907

640

10T技術資源大放送!包括但不限於:C/C++,Linux,Python,Java,PHP,人工智慧,GO等等。在公眾號內回覆對應關鍵字或框架名字,即可免費獲取!!

 你再主動一點點 640?  我們就有故事了

相關文章