最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

自定義類加載器的父類為何是AppClassLoader說(shuō)明

 更新時(shí)間:2022年11月21日 09:26:08   作者:小小少年_  
這篇文章主要介紹了自定義類加載器的父類為何是AppClassLoader說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

首先有一個(gè)概念要了解

我們通常說(shuō)在jdk中,默認(rèn)有三個(gè)類加載器,bootstrapClassLoader、ExtClassLoader、AppClassLoader,我們說(shuō)前者是后者的父類加載器,但是實(shí)際上,這里所謂的父類加載器,并不是Java中的父子類繼承關(guān)系,而是說(shuō):

  • AppClassLoader中有一個(gè)parentClassLoader設(shè)置的值是ExtClassLoader
  • ExtClassLoader中的parentClassLoader設(shè)置的是bootstrapClassLoader
  • 我們自定義的類加載器,對(duì)應(yīng)的parentClassLoader是AppClassLoader

我們?nèi)绻远x一個(gè)類加載器,默認(rèn)設(shè)置的父類加載器是AppClassLoader,這個(gè)原因是在因?yàn)樵诔跏蓟远x類加載器的時(shí)候,會(huì)指定其parentClassLoader為AppClassLoader

Launcher

這個(gè)類是jre中用來(lái)啟動(dòng)main()方法的入口,在這個(gè)類中,我們著重關(guān)注的是初始化構(gòu)造方法

public Launcher() {
? ? Launcher.ExtClassLoader var1;
? ? try {
? ? ?? ?// 初始化extClassLoader
? ? ? ? var1 = Launcher.ExtClassLoader.getExtClassLoader();
? ? } catch (IOException var10) {
? ? ? ? throw new InternalError("Could not create extension class loader", var10);
? ? }

? ? try {
? ? ?? ?// 初始化appClassLoader,這里的這個(gè)賦值是比較重要的
? ? ? ? this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
? ? } catch (IOException var9) {
? ? ? ? throw new InternalError("Could not create application class loader", var9);
? ? }

? ? Thread.currentThread().setContextClassLoader(this.loader);
? ? String var2 = System.getProperty("java.security.manager");
? ? if (var2 != null) {
? ? ? ? SecurityManager var3 = null;
? ? ? ? if (!"".equals(var2) && !"default".equals(var2)) {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? var3 = (SecurityManager)this.loader.loadClass(var2).newInstance();
? ? ? ? ? ? } catch (IllegalAccessException var5) {
? ? ? ? ? ? } catch (InstantiationException var6) {
? ? ? ? ? ? } catch (ClassNotFoundException var7) {
? ? ? ? ? ? } catch (ClassCastException var8) {
? ? ? ? ? ? }
? ? ? ? } else {
? ? ? ? ? ? var3 = new SecurityManager();
? ? ? ? }

? ? ? ? if (var3 == null) {
? ? ? ? ? ? throw new InternalError("Could not create SecurityManager: " + var2);
? ? ? ? }

? ? ? ? System.setSecurityManager(var3);
? ? }
}

這個(gè)構(gòu)造方法中,我目前所了解到的,就是初始化了AppClassLoader和ExtClassLoader,并且,和這篇博客相關(guān)的,我們只需要關(guān)心this.loader這個(gè)全局變量,這個(gè)全局變量存放的是AppClassLoader的對(duì)象信息

構(gòu)造一個(gè)自定義類加載器

我們要自定義一個(gè)類加載器,只需要繼承classLoader,并重寫findClass()方法即可

class MyClassLoader extends ClassLoader {

? ? private String loadPath;

? ? public String getLoadPath() {
? ? ? ? return loadPath;
? ? }

? ? public void setLoadPath(String loadPath) {
? ? ? ? this.loadPath = loadPath;
? ? }

? ? @Override
? ? protected Class<?> findClass(String name) throws ClassNotFoundException {
? ? ? ? try {
? ? ? ? ? ? byte[] bytes = loadByte(name);
? ? ? ? ? ? return defineClass(name, bytes, 0, bytes.length);
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? System.out.println(e.getMessage());
? ? ? ? }
? ? ? ? return null;
? ? }

? ? private byte[] loadByte(String className) throws Exception {
? ? ? ? className = className.replaceAll("\\.", "/");
? ? ? ? FileInputStream fileInputStream = new FileInputStream(loadPath + "/" + className + ".class");
? ? ? ? int available = fileInputStream.available();
? ? ? ? byte[] data = new byte[available];
? ? ? ? fileInputStream.read(data);
? ? ? ? fileInputStream.close();
? ? ? ? return data;
? ? }
}

那么,我在使用的時(shí)候,只需要調(diào)用new MyClassLoaderTest()即可

new MyClassLoaderTest()

我們說(shuō),自定義的類解析器對(duì)應(yīng)的parentClassLoader,就是在空參構(gòu)造函數(shù)中被賦值的

因?yàn)镸yClassLoaderTest繼承了ClassLoader,所以,會(huì)調(diào)用到ClassLoader的空參構(gòu)造函數(shù)

protected ClassLoader() {
? ? this(checkCreateClassLoader(), getSystemClassLoader());
}
private ClassLoader(Void unused, ClassLoader parent) {
? ? this.parent = parent;
? ? if (ParallelLoaders.isRegistered(this.getClass())) {
? ? ? ? parallelLockMap = new ConcurrentHashMap<>();
? ? ? ? package2certs = new ConcurrentHashMap<>();
? ? ? ? domains =
? ? ? ? ? ? Collections.synchronizedSet(new HashSet<ProtectionDomain>());
? ? ? ? assertionLock = new Object();
? ? } else {
? ? ? ? // no finer-grained lock; lock on the classloader instance
? ? ? ? parallelLockMap = null;
? ? ? ? package2certs = new Hashtable<>();
? ? ? ? domains = new HashSet<>();
? ? ? ? assertionLock = this;
? ? }
}

我們會(huì)發(fā)現(xiàn),parentClassLoader就是getSystemClassLoader()返回的,

java.lang.ClassLoader#getSystemClassLoader
?? ?java.lang.ClassLoader#initSystemClassLoader


// 這個(gè)方法中的其他變量我們可以暫時(shí)先不關(guān)心,我們看到有獲取到一個(gè)Launcher對(duì)象
private static synchronized void initSystemClassLoader() {
? ? if (!sclSet) {
? ? ? ? if (scl != null)
? ? ? ? ? ? throw new IllegalStateException("recursive invocation");
? ? ? ? sun.misc.Launcher l = sun.misc.Launcher.getLauncher();
? ? ? ? if (l != null) {
? ? ? ? ? ? Throwable oops = null;
? ? ? ? ? ? // 在這里調(diào)用其getClassLoader()方法,將返回的值,賦值給scl,而這個(gè)scl就是入?yún)⒅械膒arent
? ? ? ? ? ? scl = l.getClassLoader();
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? scl = AccessController.doPrivileged(
? ? ? ? ? ? ? ? ? ? new SystemClassLoaderAction(scl));
? ? ? ? ? ? } catch (PrivilegedActionException pae) {
? ? ? ? ? ? ? ? oops = pae.getCause();
? ? ? ? ? ? ? ? if (oops instanceof InvocationTargetException) {
? ? ? ? ? ? ? ? ? ? oops = oops.getCause();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if (oops != null) {
? ? ? ? ? ? ? ? if (oops instanceof Error) {
? ? ? ? ? ? ? ? ? ? throw (Error) oops;
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? // wrap the exception
? ? ? ? ? ? ? ? ? ? throw new Error(oops);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? sclSet = true;
? ? }
}

這里的getClassLoader()返回的就是上面我說(shuō)明的,需要特別關(guān)注的this.classLoader這個(gè)全局變量

scl是從l.getClassLoader()這個(gè)方法獲取到的結(jié)果,那我們看下這個(gè)方法

sun.misc.Launcher#getClassLoader
public ClassLoader getClassLoader() {
? ? ? ? return this.loader;
}

可以看到,這里的getClassLoader,就是博客上面 Launcher 這個(gè)方法中賦值的this.loader;

所以,通過(guò)上面的代碼,可以發(fā)現(xiàn),我們自定義的類解析器,是在初始化的時(shí)候,指定了parent為AppClassLoader

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Springboot實(shí)現(xiàn)緩存預(yù)熱的方法

    Springboot實(shí)現(xiàn)緩存預(yù)熱的方法

    在系統(tǒng)啟動(dòng)之前通過(guò)預(yù)先將常用數(shù)據(jù)加載到緩存中,以提高緩存命中率和系統(tǒng)性能的過(guò)程,緩存預(yù)熱的目的是盡可能地避免緩存擊穿和緩存雪崩,這篇文章主要介紹了Springboot實(shí)現(xiàn)緩存預(yù)熱,需要的朋友可以參考下
    2024-03-03
  • Java實(shí)現(xiàn)圖像分割功能

    Java實(shí)現(xiàn)圖像分割功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)圖像分割功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • springSecurity之AuthenticationProvider用法解析

    springSecurity之AuthenticationProvider用法解析

    這篇文章主要介紹了springSecurity之AuthenticationProvider用法解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • spring簡(jiǎn)單MVC實(shí)現(xiàn)方法(URL映射及其參數(shù)使用、查詢(id、其他參數(shù))、增加)

    spring簡(jiǎn)單MVC實(shí)現(xiàn)方法(URL映射及其參數(shù)使用、查詢(id、其他參數(shù))、增加)

    這篇文章主要介紹了spring簡(jiǎn)單MVC實(shí)現(xiàn)方法(URL映射及其參數(shù)使用、查詢(id、其他參數(shù))、增加),方法參數(shù)使用包括在無(wú)注解下獲取參數(shù),使用@RequestParam 獲取參數(shù)的方法,每種方法講解的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • Java使用EasyExcel動(dòng)態(tài)添加自增序號(hào)列

    Java使用EasyExcel動(dòng)態(tài)添加自增序號(hào)列

    本文將介紹如何通過(guò)使用EasyExcel自定義攔截器實(shí)現(xiàn)在最終的Excel文件中新增一列自增的序號(hào)列,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Java中BeanUtils.copyProperties基本用法與小坑

    Java中BeanUtils.copyProperties基本用法與小坑

    本文主要介紹了Java中BeanUtils.copyProperties基本用法與小坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • java使用xfire搭建webservice服務(wù)的過(guò)程詳解

    java使用xfire搭建webservice服務(wù)的過(guò)程詳解

    這篇文章主要介紹了java使用xfire搭建webservice服務(wù)的過(guò)程。使用xfire搭建webService的服務(wù),可以在瀏覽器訪問(wèn)。對(duì)此感興趣的可以了解一下
    2020-07-07
  • 淺談Spring Boot、MyBatis、MyBatis-Plus 依賴版本對(duì)應(yīng)關(guān)系

    淺談Spring Boot、MyBatis、MyBatis-Plus 依賴版本對(duì)應(yīng)關(guān)系

    本文主要介紹了SpringBoot、MyBatis和MyBatis-Plus的依賴版本對(duì)應(yīng)關(guān)系,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-11-11
  • OpenCV實(shí)現(xiàn)反閾值二值化

    OpenCV實(shí)現(xiàn)反閾值二值化

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)反閾值二值化,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • SpringBoot 嵌入式web容器的啟動(dòng)原理詳解

    SpringBoot 嵌入式web容器的啟動(dòng)原理詳解

    這篇文章主要介紹了SpringBoot 嵌入式web容器的啟動(dòng)原理詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。
    2021-11-11

最新評(píng)論

深圳市| 武平县| 哈密市| 崇州市| 玉田县| 温泉县| 乌海市| 竹溪县| 北宁市| 山丹县| 北宁市| 清丰县| 泰州市| 赫章县| 土默特右旗| 汉阴县| 五河县| 改则县| 彰化市| 山东省| 卓尼县| 灌南县| 玉林市| 龙陵县| 屏山县| 台南市| 唐海县| 鹤庆县| 河北省| 泰安市| 天峨县| 利辛县| 鄢陵县| 东宁县| 思茅市| 电白县| 泰和县| 隆尧县| 雅安市| 赞皇县| 东至县|