什麼是 ClassLoader ?
我們所寫副檔名名為 .java 的程式碼,需要透過 javac 也就是 java 編譯器編譯成對應同樣名稱,
但副檔名名為 .class 的檔案。ClassLoader 的角色就是將這些 .class 檔載入成 JVM 內的 Class<?> 物件。
JVM 中內置了三個重要的 ClassLoader,分別是 BootstrapClassLoader、ExtensionClassLoader 和 AppClassLoader,那這三類之間的加載順序如下圖 。
名字 | 負責載入類別 | 載入類別 | 具體類別 |
---|---|---|---|
Bootstrap ClassLoader | 加載 JVM 運行時核心類 | JAVA_HOME/lib/rt.jar | java.util.、java.io.、java.nio.、java.lang. |
Extension ClassLoader | 加載 JVM 擴展類 | JAVA_HOME/lib/ext/*.jar | swing 系列、内置的 js 引擎、xml 解析器 |
SystemApp ClassLoader | 載入編寫的程式碼以及使用的第三方 JAR 套件 |
JVM 在加載未知類別的時候會採用哪一個 ClassLoader 呢?
在 Bootstrap、Extension、SystemApp 加載了部分類別之後,如果這時候 JVM 遇到未知的類別(調用某一個靜態類別方法、或是透過某類別物件呼叫方法) 就會以調用這方法所在的類別加載器,去加載這個未知類別。這時候會問,JVM 怎麼知道,調用的這個人是用哪一個類別加載器去載入的,JVM 再將某.class 檔案載入成 java.lang.Class 物件的時候,就會儲存這個訊息,可以透過 java.lang.Class 的 getClassLoader() 獲得這個訊息。
Spring Boot restart 是採用哪一個 ClassLoader ?
以下為 Spring Boot 採用的 ClassLoader
org.springframework.boot.devtools.restart.classloader.RestartClassLoader
看向紅色箭頭處,其實是 java.net.URLClassLoader ,會發現這是一個 URLClassLoader ,此處的 URL 可以代表file:// 的位置、http:// 、又或是 ftp:// ,可參考下方資料 URLClassLoader ,內有 URLClassLoader 的一種用法。
參考資料
老大難的 Java ClassLoader 再不理解就老了
https://zhuanlan.zhihu.com/p/51374915
淺談Java ClassLoader
https://zhuanlan.zhihu.com/p/40574557
{Java 8} java.lang.Class
https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html
{官方} RestartClassLoader
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/devtools/restart/classloader/RestartClassLoader.html
URLClassLoader 用法
https://www.cnblogs.com/fysola/p/6100961.html
自定義ClassLoader
https://openhome.cc/Gossip/JavaEssence/MyClassLoader.html