Java類載入器深入理解
本篇文章主要是詳細寫一下個人對Java ClassLoader的理解。
首先回顧一下,java虛擬機器載入java類的步驟:java檔案經過編譯器編譯後變成位元組碼檔案(.class檔案),類載入器(ClassLoader)讀取.class檔案,並且轉換成java.lang.Class的一個例項,最後通過newInstance方法建立該類的一個物件。ClassLoader的作用就是根據一個類名,找到對應的位元組碼,根據這些位元組碼定義出對應的類,該類就是java.lang.Class的一個例項。
類載入器的組織結構
java有三個初始類載入器,當java虛擬機器啟動時,它們會按照以下順序啟動:Bootstrap classloader -> extension classloader -> system classloader。三者的關係:bootstrap classloader是extension classloader的parent,extension classloader是system classloader的parent。
bootstrap classloader
它是最原始的類載入器,並不是由java程式碼寫的,是由原生程式碼編寫的。Java有一次編譯、所有平臺執行的效果,就是因為它寫了一份功能相同,但針對不同平臺不同語言實現的底層程式碼。它負責載入java核心庫,大家可執行以下程式碼,看看自己本地的java核心庫在哪裡:
URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs(); for (int i = 0; i < urls.length; i++) { System.out.println(urls[i].toExternalForm()); }
本人的執行結果:
file:/home/eric/jdk1.6.0_35/jre/lib/resources.jar file:/home/eric/jdk1.6.0_35/jre/lib/rt.jar file:/home/eric/jdk1.6.0_35/jre/lib/sunrsasign.jar file:/home/eric/jdk1.6.0_35/jre/lib/jsse.jar file:/home/eric/jdk1.6.0_35/jre/lib/jce.jar file:/home/eric/jdk1.6.0_35/jre/lib/charsets.jar file:/home/eric/jdk1.6.0_35/jre/lib/modules/jdk.boot.jar file:/home/eric/jdk1.6.0_35/jre/classes
extension classloader
它用來載入JRE的擴充套件目錄(JAVA_HOME/jre/lib/ext或java.ext.dirs系統屬性指定的)JAR的類包。注意,因為它是bootstrap classloader載入的,所以當你執行:
ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent(); System.out.println("the parent of extension classloader : "+extensionClassloader.getParent());
輸出的是:the parent of extension classloader : null
system classloader
它用於載入classpath目錄下的jar包,我們寫的java類,一般都是由它載入,除非你自己制定個人的類載入器。
全盤負責委託機制
classloader載入類時,使用全盤負責委託機制,可以分開兩部分理解:全盤負責,委託。
全盤負責機制:若類A呼叫了類B,則類B和類B所引入的所有jar包,都由類A的類載入器統一載入。
委託機制:類載入器在載入類A時,會優先讓父載入器載入,當父載入器載入不到,再找父父載入器,一直找到bootstrap classloader都找不到,才自己去相關的路徑去尋找載入。以下是ClassLoader的原始碼:
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { try { if (parent != null) { //從父載入器載入 c = parent.loadClass(name, false); } else { //從bootstrap loader載入 c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. c = findClass(name); } } if (resolve) { resolveClass(c); } return c; }
舉個例子,類載入器載入類A的過程:
1,判斷是否已經載入過,在cache裡面查詢,若有,跳7;否則下一步
2,判斷當前載入器是否有父載入器,若無,則當前為ext classloader,跳去4;否則下一步
3,請求父載入器載入該類,若載入成功,跳7;若不成功,即父載入器不能找到該類,跳2
4,請求jvm的bootstrap classloader載入,若載入成功,跳7;若失敗,跳5
5,當前載入器自己載入,若成功,跳7;否則,跳6
6,丟擲ClassNotFoundException
7,返回Class
編寫自己的類載入器
Java載入類的過程,實質上是呼叫loadClass()方法,loadClass中呼叫findLoadedClass()方法來檢查該類是否已經被載入過,如果沒有就會呼叫父載入器的loadClass(),如果父載入器無法載入該類,就呼叫findClass()來查詢該類。
所以我們要做的就是新建MyClassLoader繼承java.lang.ClassLoader,重寫其中的findClass()方法。主要是重新設計查詢位元組碼檔案的方案,然後呼叫definedClass來返回。
本人寫了一個demo,用自己的類載入器去載入指定java檔案,且帶有熱部署效果,具體請檢視以下url。
Demo地址:http://git.oschina.net/ericquan8/hot-deploy
相關文章
- 深入理解Java類載入器(ClassLoader)Java
- 深入理解JVM類載入器JVM
- 深入理解Java虛擬機器(類載入機制)Java虛擬機
- 深入理解Java虛擬機器 - 類載入機制Java虛擬機
- 深入理解Java虛擬機器 --- 類載入機制Java虛擬機
- 深入探討 Java 類載入器Java
- Java基礎——深入理解類的載入Java
- 深入理解JVM(六)——類載入器原理JVM
- [深入理解Java虛擬機器]第七章 類載入器Java虛擬機
- 深入理解Java:類載入機制及反射Java反射
- 深入理解JVM之類載入JVM
- 深入理解JVM虛擬機器6:深入理解JVM類載入機制JVM虛擬機
- 阿里面試題,深入理解Java類載入機制阿里面試題Java
- 深入理解JVM,虛擬機器類載入機制JVM虛擬機
- 深入理解OSGi類載入機制
- 深入理解JVM類載入機制JVM
- (深入理解 Java虛擬機器)一篇文章帶你深入瞭解Java 虛擬機器類載入器Java虛擬機
- 【進階之路】深入理解Java虛擬機器的類載入機制(長文)Java虛擬機
- 《深入理解java虛擬機器》學習筆記6——類載入機制Java虛擬機筆記
- [深入理解Java虛擬機器]第七章 類載入的時機Java虛擬機
- [深入理解Java虛擬機器]第七章 類載入的過程Java虛擬機
- Java類載入原理解析Java
- 深入理解JVM(③)虛擬機器的類載入時機JVM虛擬機
- 深入理解JVM(③)虛擬機器的類載入過程JVM虛擬機
- 深入理解JVM——(四)類載入機制JVM
- 深入理解JVM(③)虛擬機器的類載入器(雙親委派模型)JVM虛擬機模型
- 深入理解虛擬機器之虛擬機器類載入機制虛擬機
- 深入理解JVM(四)類載入的時機JVM
- 深入理解java的抽象類和介面(轉載)Java抽象
- Java 類載入器以及載入機制Java
- 《深入理解java虛擬機器》學習筆記8——Tomcat類載入器體系結構Java虛擬機筆記Tomcat
- 深入理解jvm-2Edition-虛擬機器類載入機制JVM虛擬機
- Java類載入器詳解Java
- Java-JVM-類載入器JavaJVM
- 深入 Java 類載入全流程,值得你收藏Java
- 《深入理解java虛擬機器》第七章讀書筆記——虛擬機器類載入機制Java虛擬機筆記
- Java基礎-類載入器以及載入機制Java
- Java類載入機制與Tomcat類載入器架構JavaTomcat架構