1、 ClassLoader:具体的作用就是将class文件加载到jvm虚拟中去,程序就可以正确运行了

        但是,jvm启动的时候,并不会一次性加载所有的class文件,而是根据需要去动态加载。

2、 java 类加载流程:

     java语言系统自带有三个类加载器:

     Bootstrap ClassLoader (引导类加载器)最顶层的加载类,主要加载核心类库,%JRE_HOME%\lib 下边的rt.jar、resources.jar 和class等

         E:\Java\jdk1.8.0_152\jre\lib\resources.jar;

         E:\Java\jdk1.8.0_152\jre\lib\rt.jar;

         E:\Java\jdk1.8.0_152\jre\lib\sunrsasign.jar;

         E:\Java\jdk1.8.0_152\jre\lib\jsse.jar;

           E:\Java\jdk1.8.0_152\jre\lib\jce.jar;

           E:\Java\jdk1.8.0_152\jre\lib\charsets.jar;

           E:\Java\jdk1.8.0_152\jre\lib\jfr.jar;E:\Java\jdk1.8.0_152\jre\classes

         这些全是JRE目录下的jar包或者是class文件

     Extention ClassLoader (延伸类加载器)扩展类加载器,加载%JRE_HOME%\lib\ext下的jar包或class文件

     Appclass Loader也称作SystemAppClass 加载当前应用的classpath的所有类

  加载顺序 

    a、Bootstrap ClassLoader
  
  b、Extention ClassLoader

    c、Appclass Loader

    Launcher :sun.misc.Launcher,它是java虚拟机的应用入口

      

      

      其中:

         private static String bootClassPath = System.getProperty("sun.boot.class.path");     //最顶层的类加载器

                 var1 = Launcher.ExtClassLoader.getExtClassLoader();                            //延伸类加载器   

         this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);         //App应用加载器 

         Thread.currentThread().setContextClassLoader(this.loader);                  //设置AppClassLoader为线程上下文类加载器,这个文章后面部分讲解

3、ClassLoader 的源码

    

    private final ClassLoader parent;               //类加载的parent  也是一个ClassLoader

    private static ClassLoader scl;     

    

    //创建ClassLoader对象的时候将parant添加上去

    

    this(checkCreateClassLoader(), getSystemClassLoader());   //没有的情况调用getSystemClassLoader(); 方法  

    

    

    

    

    scl = l.getClassLoader(); //默认的情况通过Launcher的getClassLoader()来获取到 

                ---------其实也就是AppClassLoader为默认的父类加载

    由上可见:

       一个ClassLoader对象的parent:

         a、由外部类创建ClassLoader时直接指定一个ClassLoader为parent 

       b、由getSystemClassLoader()方法生成  ------也就是sun.misc.Laucher通过getClassLoader()

                         ------也就是AppClassLoader

         直白的说,一个classLoader创建的时如果没有指定parent,那么它的parent默认就是AppClassLoader

       c、

         var1 = Launcher.ExtClassLoader.getExtClassLoader();

         this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);

         AppClassLoader的parent是ExtClassLoader,ExtClassLoader的parent是null;

         d、ExtClassLoader的父加载器为null,但是Bootstrap CLassLoader却可以当成它的父加载器 ------为什么那 

         Bootstrap ClassLoader是由C++编写的,他本身就是虚拟机的一部分

       e、JVM初始化sun.misc.Launcher并创建ExtensionClassLoader 和 AppClassLoader实例,并且将ExtensionClassLoader设置为 AppClassLoader的父加  器                

         另外补充:  private final ClassLoader parent; 

           final修改的字段在赋值之后便不能修改,这句话的理解:final修饰的字段只能赋值一次

           private 结合 final 能实现在改类中肯定会实现其属性的实例,并且只有一次

           也就是在classLoader中有且只有一次属性赋值,并且只有一次赋值

4、 双亲委托 

    a、某个class请求加载 自身的classLoader --->父类的classLoader ----->AppClassLoader(向上委托方式) ------>缓存中查找

    b、AppClassLoader---->ExtClassLoader(向上委托方式) ----->缓存中查找

    c、ExtClassLoader---->Bootstrap(向上委托方式)----->缓存中查找

    ----------------------------------------------------------------向下查找方向

    d、Bootstrap ClassLoader 规定的路径 sun.mic.boot.class下查找 ------- %JRE_HOME%\lib 下

    e、ExtClassLoader的规定路径java.ext.dirs 下查找 --------  %JRE_HOME%\lib\ext下的jar包或class文件 

    f、AppClassLoader的路径 java.class.path下查找 ------- classpath下的所有类  

 5、 应用:

    自定义class、加密class  使得仅仅只有自己可以执行class文件

     Thread.currentThread().setContextClassLoader(this.loader);  //获取classLoader之间的关联

 

 

 

      

  

   

  

 posted on 2018-08-22 11:40  风凌月歌  阅读(205)  评论(0编辑  收藏  举报