jvm双亲委派机制详解

双亲委派机制【jvm双亲委派机制详解】?记录一下JVM的双亲委派机制学习记录 。
类加载器种类?当我们运行某一个java类的main方法时 , 首先需要由java虚拟机的类加载器将我们要执行的main方法所在的class文件加载到jvm中,这里提到的类加载器大概有4种:
引导类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如rt.jar、charsets.jar等扩展类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包应用程序类加载器:负责加载ClassPath路径下的类包,主要就是加载你自己写的那些类自定义加载器:负责加载用户自定义路径下的类包 。
?每个类加载器加载的包路径都是不同的,有各自的职责 。通过一下示例,可以看出每个类加载器加载的路径:
public class TestJDKClassLoader {public static void main(String[] args) {System.out.println(String.class.getClassLoader());System.out.println(com.sun.crypto.provider.DESKeyFactory.class.getClassLoader().getClass().getName());System.out.println(TestJDKClassLoader.class.getClassLoader().getClass().getName());System.out.println();ClassLoader appClassLoader = ClassLoader.getSystemClassLoader();ClassLoader extClassloader = appClassLoader.getParent();ClassLoader bootstrapLoader = extClassloader.getParent();System.out.println("the bootstrapLoader : " + bootstrapLoader);System.out.println("the extClassloader : " + extClassloader);System.out.println("the appClassLoader : " + appClassLoader);System.out.println();System.out.println("bootstrapLoader加载以下文件:");URL[] urls = Launcher.getBootstrapClassPath().getURLs();for (int i = 0; i < urls.length; i++) {System.out.println(urls[i]);}System.out.println();System.out.println("extClassloader加载以下文件:");System.out.println(System.getProperty("java.ext.dirs"));System.out.println();System.out.println("appClassLoader加载以下文件:");System.out.println(System.getProperty("java.class.path"));}}// 运行结果:nullsun.misc.Launcher$ExtClassLoadersun.misc.Launcher$AppClassLoaderthe bootstrapLoader : nullthe extClassloader : sun.misc.Launcher$ExtClassLoader@330bedb4the appClassLoader : sun.misc.Launcher$AppClassLoader@14dad5dcbootstrapLoader加载以下文件:file:/D:/ProgramFiles/jdk1.8.0_45_64bit/jre/lib/resources.jarfile:/D:/ProgramFiles/jdk1.8.0_45_64bit/jre/lib/rt.jarfile:/D:/ProgramFiles/jdk1.8.0_45_64bit/jre/lib/sunrsasign.jarfile:/D:/ProgramFiles/jdk1.8.0_45_64bit/jre/lib/jsse.jarfile:/D:/ProgramFiles/jdk1.8.0_45_64bit/jre/lib/jce.jarfile:/D:/ProgramFiles/jdk1.8.0_45_64bit/jre/lib/charsets.jarfile:/D:/ProgramFiles/jdk1.8.0_45_64bit/jre/lib/jfr.jarfile:/D:/ProgramFiles/jdk1.8.0_45_64bit/jre/classesextClassloader加载以下文件:D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\extappClassLoader加载以下文件:D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\charsets.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\deploy.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext\access-bridge-64.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext\cldrdata.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext\dnsns.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext\jaccess.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext\jfxrt.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext\localedata.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext\nashorn.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext\sunec.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext\sunjce_provider.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext\sunmscapi.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext\sunpkcs11.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\ext\zipfs.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\javaws.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\jce.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\jfr.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\jfxswt.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\jsse.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\management-agent.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\plugin.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\resources.jar;D:\ProgramFiles\jdk1.8.0_45_64bit\jre\lib\rt.jar;D:\Files\learn\tuling\jvm-demo\target\classes;D:\ProgramFiles\ideaIU-2021.3.3.win\lib\idea_rt.jarProcess finished with exit code 0appClassLoader虽然打印的内容虽然很多,但它只需要加载target目录下的文件 。
双亲委派机制?虽然基本只有4种类加载器,但这4种类加载器之间是存在一定的关联关系的 。如下图:

jvm双亲委派机制详解

文章插图
?加载某个类时会先委托给父加载器寻找目标类,找不到再委托上层父类加载器加载,所有的父类加载器在自己的加载类路径下都找不到目标类,则在自己的类加载路径中寻找并载入目标类 。
?比如上面的TestJDKClassLoader , 首先会委托应用程序类加载 , 应用程序类加载器则委托扩展类加载器加载,扩展类加载器则委托引导类加载器加载,引导类加载器在它的类加载路径下找不到TestJDKClassLoader.class文件 , 则向下委托扩展类加载器加载,扩展类加载器加载不到则委托应用程序类加载器自己加载,于是应用程序类加载器在target目录下找到并载入了TestJDKClassLoader.class文件 。

推荐阅读