1. 程式人生 > >java獲取類載入器

java獲取類載入器

獲取類載入器的方法:

 		//擴充套件類載入器Main
        ClassLoader classLoader = MainTest.class.getClassLoader();
        //表示當前執行緒的類載入器——應用程式類載入器
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        //—啟動類載入器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader
();

在一個簡單的main方法中,返回對應的類載入器是相同的:
在這裡插入圖片描述
在類載入器雙親委派模型中(可看本文後面的雙親委派模型介紹),應用程式載入器的定義是:這個類載入器由sun.misc.Launcher$AppClassLoader載入實現。spring的類載入器的型別為“”應用程式載入器“”怎麼看出來的呢。下圖:
在這裡插入圖片描述
這個類載入器是什麼時候設定的呢?看DefaultResourceLoader的無參建構函式,在類初始化時設定的。

public DefaultResourceLoader() {
	this.classLoader = ClassUtils.getDefaultClassLoader();
}

可以進一步檢視類載入器的生成。進入ClassUtils.getDefaultClassLoader()方法如下。

 public static ClassLoader getDefaultClassLoader() {
    		ClassLoader cl = null;
    		try {
    			cl = Thread.currentThread().getContextClassLoader();
    		}
    		catch (Throwable ex) {
    			// Cannot access thread context ClassLoader - falling back...
} if (cl == null) { // No thread context class loader -> use class loader of this class. cl = ClassUtils.class.getClassLoader(); if (cl == null) { // getClassLoader() returning null indicates the bootstrap ClassLoader try { cl = ClassLoader.getSystemClassLoader(); } catch (Throwable ex) { // Cannot access system ClassLoader - oh well, maybe the caller can live with null... } } } return cl; }

2、 雙親委派模型介紹(摘自《深入理解java虛擬機器》虛擬機器類載入機制)
類載入器的雙親委派模型,如下圖所示,雙親委派模型要求除了頂層的啟動類載入器外,其餘的類載入器都應當有自己的父類載入器。這裡類載入器之間的父子關係一般不會以繼承的關係來實現,而是都使用組合關係來複用父載入器。spring中提供的方法 getDefaultClassLoader()就是使用組合關係來複用父類載入器。
在這裡插入圖片描述
雙親委派模型的工作過程是:如果一個類載入器收到了類載入請求,它首先不會自己去嘗試載入這個類,而是把這個請求委派給父類載入器去完成,每一個層次的類載入器都是如此,因此所有的載入請求都應該傳送到頂層的啟動類載入器中,只有當父載入器反饋自己無法完成這個載入請求(它的搜尋範圍中沒有找到所需的類)時,子載入器才會嘗試自己去載入。

從java虛擬機器的角度講,只存在兩種不同的類載入器:一種是啟動類載入器(Bootstrap ClassLoader),由C++實現,另一種就是所有其它的載入器,是由java實現的,獨立於虛擬機器外部,並且全都繼承自java.lang.ClassLoader。

從java開發人員來講,類載入器還可以劃分的更細緻一些:

1、 啟動類載入器(Bootstrap ClassLoader):這個類載入器負責將存放在<JAVA_HOME>\lib目錄中,或者被-XbootClasspath引數所指定的路徑中的,並且是虛擬機器識別的(僅按照檔名識別,如rt.jar,名字不符合的類庫即使放在lib目錄中也不會被載入)類庫載入到虛擬機器記憶體中。啟動類載入器無法直接被java程式引用,使用者在編寫自定義類載入器時,如果需要把載入請求委派給引導類載入器,那直接使用null代替即可。

2、 擴充套件類載入器(Extension ClassLoader):這個載入器由sun.misc.Launcher$ExtClassLoader實現,它負責載入<JAVA_HOME>\lib\ext目錄中,或者被java.ext.dirs系統變數所指定的路徑中的類庫,開發者可以直接使用擴充套件類載入器。

3、 應用程式類載入器(Application ClassLoader):這個類載入器由sun.misc.Launcher$AppClassLoader實現。由於這個類載入器是ClassLoader中的getSystemClassLoader()方法的返回值,所以一般也稱它為系統類載入器,它負責載入使用者類路徑(classpath)上指定的類庫,開發者可以直接使用這個類載入器,如果應用程式中沒有自定義過自己的類載入器,一般情況下這個就是程式中的預設類載入器。

來源:CSDN
原文:https://blog.csdn.net/sum__mer/article/details/52589762