美文网首页
简述Java的类加载

简述Java的类加载

作者: 黑铁大魔王 | 来源:发表于2020-04-10 19:44 被阅读0次

    Java的类加载器

    耳熟能详,不,眼熟能祥的模型图


    image-20200410181230808.png

    简单说一下:

    上图不太精确,首先他们3个不是父子继承关系,只是上下级关系。

    App接到任务不管能不能处理,先请示领导Ext

    Ext接到任务不管能不能处理,先请示领导BootStrap

    BootStrap接到任务,发现自己能处理,就处理了,不能处理,就还给Ext

    Ext同理,自己处理或者还给App

    什么是类加载:

    简单的说,类加载就是把 *.class文件从磁盘干到jvm内存里

    那么这里就需要做如下工作:

    1. 找到*.class文件在磁盘的位置
    2. 把这个class文件变成一个class实例
    3. 1,2之间有一些验证操作
    

    从代码的角度来看:

    ClassLoader.java是所有类加载器的顶级类(不包含启动类加载器)
    java代码的所有类加载器都会继承到ClassLoader,ClassLoader里有loadClass(), findClass(), defineClass()
    类加载时会调用loadClass(),loadClass()里 会调用findClass(), findClass()里调用defineClass()
    findClass顾名思义就是找到*.class文件,根据全限定名去找
    defineClass是把找到的文件转换成class实例(这是jdk源码注释:Converts an array of bytes into an instance of class)
    loadClass在最外层被调用

    从tomcat的WebappClassLoader来看:

    tomcat的webapp类加载器用来加载webapp下的资源,这样是为了做到app隔离,避免全限定名相同的类加载混乱
    webappClassLoader的loadClass()方法在加载之前会做一系列判断,比如被加载类是不是j2se的类,如果是就直接用启动类加载器加载

    image-20200410190753102.png

    再比如:是否是非webapp专有的资源,如果是,就让其上一级加载

    image-20200410190951121.png image-20200410191014053.png

    截图放不下,就不在贴出了,主要就是通过路径什么的来加以限定,确定这个类是否真的需要有WebappClassLoader来加载
    如果真需要WebappClassLoader加载,那么就执行重写的findClass(name)方法,在findClass里调用自己的findClassInternal()方法一顿搞,最后来到defineClass()里,得到class实例,这里的defineClass()方法是父类方法(SecureClassLoader,SecureClassLoader也会继续调用他的父类ClassLoader里的defineClass方法, ClassLoader里继续会调用defineClass1(),看到数字结尾的方法,那就是native方法了)

    再往后呢,如果webappClassLoader没成功加载,加载不了了,那咋办了。这就要去找领导了,让领导处理吧


    image-20200410192922031.png

    总结下:tomcat打破双亲委派是在加载webapp自己的类时,只用WebappClassLoader加载,而不会向上传递,找自己的上级处理,自己能加载就加载了

    补充一点:jdk里的ExtClassLoader,AppClassLoader都继承子URLClassLoader,其实,他们都是通过类的全限定名去findClass,只不过ExtClassLoader,AppClassLoader在加载时会通过自身的加载路径范围与被加载类的全限定名比较,看看是否属于自己的权利范围。


    image-20200410193522584.png

    相关文章

      网友评论

          本文标题:简述Java的类加载

          本文链接:https://www.haomeiwen.com/subject/diudmhtx.html