美文网首页
Classloader总结

Classloader总结

作者: 简书徐小耳 | 来源:发表于2019-03-15 17:49 被阅读0次

    ClassLoader

    classloader的最终目标是将我们的class文件变成字节,然后加载进来

    BootStrap的classloader是为null,是由C++编写的。

    • 加载jre/目录下的核心库

    Launcher内部包含ExtClassLoader和AppClassLoader

    • ExtClassLoader:加载/jre/lib/ext/目录下的扩展包
    • AppClassLoader:加载CLASSPATH路径下的包
    • 上述的Launcher类使用两个classloader加载我们永远无法debugger,在我们项目启动好的时候已经完成了加载。
    • 这个2个classLoader基本都是继承了URLClassLoader

    URLClassLoader

    • 该classloader用于把一切资源变成URL(这边URL不是指的我们网址,而是指可以统一资源定位的意思,即通过URL可以找到我们的资源)

    • 以/结尾的认为是目录,否则就是JAR文件

    • 同时该URL还增加了访问全限

    自定义的classloader

    • 个人觉得自定义classloader主要是为了修改2个地方
    • 1.classloader加载的逻辑,即是否遵循主流的双亲委派模式,还是设置自己的加载模式
    • 2.获取class文件二进制流的方式,目前urlClassloader只是提供了目录和jar文件,我们可以增加从网络,本地class文件等等。

    classLoader的拾遗

    • 每次调用defineClass 传入的必须是一个完整的class文件

    • 当我们使用文件的时候她回去这个文件下面寻找com.marshall.Controller.class文件

        File file = new File("D:\\controller");
            MyClassLoader myClassLoader = new MyClassLoader(new URL[]{file.toURI().toURL()});
            Class clazz1 = myClassLoader.loadClass("com.marshall.Controller");
          Object o=  clazz1.newInstance();
          clazz1.getDeclaredMethod("getSay").invoke(o);
            System.out.println("");
    
    • 当我们使用Jar包是使用JarFile去获取JAR包然后去com/marshall/Controller.class寻找com.marshall.Controller.class
    • 需要注意的是我们一般打包出来的boot类型的目录都是包含BOOT-INF,所以我们需要特殊处理。
       File file = new File("D:\\springTest-1.0-SNAPSHOT2.jar");
            MyClassLoader myClassLoader = new MyClassLoader(new URL[]{file.toURI().toURL()});
            JarFile jarFile=new JarFile("D:\\springTest-1.0-SNAPSHOT2.jar");
           
            Class clazz1 = myClassLoader.loadClass("com.marshall.Controller");
    
    • tomcat 通过解压war得方式得到文件进而可以对Class文件进行处理 对于lib中得jar包也可以处理。具体解压方法可以看ContextConfig的fixDocBase方法,最终调用的是ExpandWar.expand(host, war, pathName);

    • tomcat的解压就是创建一个文件然后把war里面的复制到薪文件中即可

    • loadClass:重写它就无法按照双亲加载模式

    • findClass:留给子类实现,URLClassLoader是从ClassPathsURL中获取Resource

    • resolveClass:一般是去进行连接这一步,包含各种验证(字节验证等)

    • defineClass:这个方法JDK 重载了很多主要是为了方便各种形式的入参,但是最终都是获取字节数组然后生成Class

    相关文章

      网友评论

          本文标题:Classloader总结

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