ClassLoader

作用:加載.class文件到jvm中
觸發(fā)節(jié)點:

  1. 執(zhí)行new操作
  2. Class.forName
  3. classloader.loadclass

Java內置ClassLoader

BootstrapClassloader

最頂層的類加載器姥份,主要用來加載Java核心類,如rt.jar喳资、resources.jar钥平、charsets.jar等嫉晶。它不是 java.lang.ClassLoader的子類天吓,而是由JVM自身實現的該類c 語言實現,Java程序訪問不到該加載器祭陷。

        URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();    
        for (int i = 0; i < urls.length; i++) {    
            System.out.println(urls[i].toExternalForm());    
        }

ExtClassloader

擴展類加載器,主要負責加載Java的擴展類庫趣席,默認加載JAVA_HOME/jre/lib/ext/目下的所有jar包或者由java.ext.dirs系統(tǒng)屬性指定的jar包兵志。放入這個目錄下的jar包對所有AppClassloader都是可見的(后面會知道ExtClassloader是AppClassloader的父加載器)。那么ext都是在那些地方加載類內:

System.getProperty("java.ext.dirs")

AppClassloader

它負責在JVM啟動時宣肚,加載來自 CLASSPATH下的Jar包想罕。調用ClassLoader.getSystemClassLoader()可以獲取該類加載器。如果沒有特別指定霉涨,則用戶自定義的任何類加載器都將該類加載器作為它的父加載器,這點通過ClassLoader的無參構造函數可以知道如下:

    protected ClassLoader() {
        this(checkCreateClassLoader(), getSystemClassLoader());
    }

執(zhí)行以下代碼即可獲得classpath加載路徑:

System.out.println(System.getProperty("java.class.path"));

內置Classloader關系

一般我們都認為ExtClassloader的父類加載器是BootStarpClassloader按价,但是其實他們之間根本是沒有父子關系的,只是在ExtClassloader找不到要加載類時候會去委托BootStrap加載器去加載笙瑟。
通過如下代碼可以知道父加載器為null

ClassLoader.getSystemClassLoader().getParent().getParent()

Classloader原理

Java類加載器使用的是委托機制楼镐,也就是子類加載器在加載一個類時候會讓父類來加載,保證了安全往枷。例如框产,String已經在啟動時就被引導類加載器(Bootstrcp ClassLoader)加載凄杯,所以用戶自定義的ClassLoader永遠也無法加載一個自己寫的String。

class ClassLoader {
  // name是要加載的類全名
  protected Class<?> loadClass(String name, boolean resolve) {
    synchronized (getClassLoadingLock(name)) {
            Class<?> c = findLoadedClass(name);
            if (c == null) { // 如果該類已經被加載就直接return
              if (parent != null) {
                        c = parent.loadClass(name, false);  // 尋找父classLoader加載
              } else {
                        c = findBootstrapClassOrNull(name); // 沒有父classLoader就委派給bootstrap類加載加載
              }
            }
            
            if (c == null) {
                    // 如果所有父類加載器都無法加載秉宿,再通過當前加載器定義的findClass方法進行加載戒突。
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            
            return c;
    }
  }
}

從上面源碼知道要想修改類加載委托機制,實現自己的載入策略 可以通過覆蓋ClassLoader的findClass方法或者覆蓋loadClass方法來實現描睦。

JVM初始化類加載器

class Launcher {
  public Launcher() { // 構造方法
    localExtClassLoader = ExtClassLoader.getExtClassLoader();   // 創(chuàng)建ExtClassLoader
    //然后以ExtClassloader作為父加載器創(chuàng)建了AppClassLoader
    this.loader = AppClassLoader.getAppClassLoader(localExtClassLoader);
    // 默認的線程上下文類加載器是AppClassLoader
    Thread.currentThread().setContextClassLoader(this.loader);
  }

  private static File[] getExtDirs()  {  
      // ExtClassloader要加載的jar包路徑
      String str = System.getProperty("java.ext.dirs");  
      File[] arrayOfFile;  
      if (str != null)  
      {  
        StringTokenizer localStringTokenizer = new StringTokenizer(str, File.pathSeparator);  

        int i = localStringTokenizer.countTokens();  
        arrayOfFile = new File[i];  
        for (int j = 0; j < i; j++) {  
          arrayOfFile[j] = new File(localStringTokenizer.nextToken());  
        }  
      }  
      else  
      {  
        arrayOfFile = new File[0];  
      }  
      return arrayOfFile;  
    }

    public static ClassLoader getAppClassLoader(final ClassLoader paramClassLoader)  
      throws IOException  
    {  //可知AppClassLoader類加載路徑為java.class.path
      String str = System.getProperty("java.class.path");  
      final File[] arrayOfFile = str == null ? new File[0] : Launcher.getClassPath(str);  

      (ClassLoader)AccessController.doPrivileged(new PrivilegedAction()  
      {  
        public Launcher.AppClassLoader run()  
        {  
          URL[] arrayOfURL = this.val$s == null ? new URL[0] : Launcher.pathToURLs(arrayOfFile);  

          return new Launcher.AppClassLoader(arrayOfURL, paramClassLoader);  
        }  
      });  
    }
}

ContextClassLoader

  1. 當父類加載器需要加載子類加載器中的資源時候可以通過設置和獲取線程上下文類加載器來實現膊存。
  2. 一個類加載器要使用不在當前類加載器類查找路徑路徑中的情況,這種情況下可以新建一個在指定路徑查找類的類加載器
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末忱叭,一起剝皮案震驚了整個濱河市膝舅,隨后出現的幾起案子,更是在濱河造成了極大的恐慌窑多,老刑警劉巖仍稀,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異埂息,居然都是意外死亡技潘,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門千康,熙熙樓的掌柜王于貴愁眉苦臉地迎上來享幽,“玉大人,你說我怎么就攤上這事拾弃≈底” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵豪椿,是天一觀的道長奔坟。 經常有香客問我,道長搭盾,這世上最難降的妖魔是什么咳秉? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮鸯隅,結果婚禮上澜建,老公的妹妹穿的比我還像新娘。我一直安慰自己蝌以,他們只是感情好炕舵,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著跟畅,像睡著了一般咽筋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上碍彭,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天晤硕,我揣著相機與錄音悼潭,去河邊找鬼。 笑死舞箍,一個胖子當著我的面吹牛舰褪,可吹牛的內容都是我干的。 我是一名探鬼主播疏橄,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼占拍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了捎迫?” 一聲冷哼從身側響起晃酒,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎窄绒,沒想到半個月后贝次,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡彰导,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年蛔翅,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片位谋。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡山析,死狀恐怖,靈堂內的尸體忽然破棺而出掏父,到底是詐尸還是另有隱情笋轨,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布赊淑,位于F島的核電站爵政,受9級特大地震影響,放射性物質發(fā)生泄漏膏燃。R本人自食惡果不足惜茂卦,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望组哩。 院中可真熱鬧,春花似錦处渣、人聲如沸伶贰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽黍衙。三九已至,卻和暖如春荠诬,著一層夾襖步出監(jiān)牢的瞬間琅翻,已是汗流浹背位仁。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留方椎,地道東北人聂抢。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像棠众,于是被迫代替她去往敵國和親琳疏。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內容

  • 作者簡介 原創(chuàng)微信公眾號郭霖 WeChat ID: guolin_blog 本篇是fank909的第四篇投稿,詳細...
    木木00閱讀 1,609評論 1 14
  • 一新荤、什么是Classloader 一個Java程序要想運行起來揽趾,首先需要經過編譯生成 .class文件,然后創(chuàng)建一...
    阿里加多閱讀 2,579評論 1 21
  • 安卓插件化越來越流行,其中用到的技術不外乎加載外部的資源和加載外部的代碼,關于加載外部資源我之前寫過一篇文章《安卓...
    嘉偉咯閱讀 1,615評論 5 14
  • 文/天水石逸 伴著皎潔的月光回想著一切苛骨,從大學畢業(yè)至今恍恍惚惚的一年里篱瞎,自己從一個伴著滿腔熱血的追夢少年,變成到至...
    天水石逸閱讀 715評論 6 7