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