美文网首页
类加载,双亲委派

类加载,双亲委派

作者: 小周爱吃瓜 | 来源:发表于2022-03-10 23:36 被阅读0次

    类加载机制:

    指的是将类的字节码文件包含的数据写入到内存中。 关于字节码文件可以用javac ,javap -v xxx.class文件查看. 也可以用bytecode viewer工具查看.

    字节码文件--->内存--->数据访问

    来源: 可以从本地系统,网络,zip包,动态编译,动态代理,加密文件获取.

    1.装载: 通过全类名获取二进制流进行加载,同时方法区和堆就同时有了数据. 2.验证:是否符合JVM规范: 2.1 文件格式 字节码文件地址值规范,版本号 2.2 元数据信息是否规范 2.3 符号引用 等 3.准备阶段: 为非final的静态变量赋值,设置基本变量的默认初始值. 4.解析: 符号引用转化成直接引用。 比如调用方法a(),a()地址为#f00`,这个a就是符号引用,f00就是直接引用, 加载时期就能决定的叫做静态的链接,一些代码要在运行时才能决定叫做动态链接. 5.初始化 说白了就是构造方法的调用过程. 由开发者决定那些数据被初始化. 包括静态代码块,构造方法,构造代码块,成员变量数据等. 6.使用: 主动使用类的时候,包括new,Classforname,初始化子类及其父类等。 7.卸载: 常问 7.1 类实例被回收了,堆中没有该类的实例 7.2 加载该类的ClassLoader被回收了 7.3 没有被引用了 总结: 自己挂了,没有引用它了,加载器也被回收了.

    双亲委派: 负责读取java字节码文件,并且转化成java.lang.Class类的一个实例代码模块。

    BootstrapClassLoader 顶层: 加载/jre/lib 可以理解成核心类的class

    ExtensionClassLoader 中间: 加载平台扩展的jar包

    AppClassLoader下层: 加载classpath中指定的jar包

    好处: 安全,不然随便写个字符串都能被加载。 效率高,加载过的不会被加载了 重写loadClass,可以指定自己的类加载器 findClass(不要轻易尝试,会带来很多问题)

    为什么要打破? 比如Tomcat,部署了不同版本的包,A1,A2版本,路径相同下的类名相同, 这样会出现覆盖的情况,各自需要的类会冲突。

    JDBC 在bootxxClass加载的类要用AppClassLoader加载,矛盾了 Tomcat 自己的WebAppClassLoader加载自己目录下的class文件,不会向上传递.

    第二天对第一天的补充:

    类加载机制的好处:
    沙箱机制: 不能随意写个String就被加载了
    避免类的重复加载
    package com.daily.tuling726;

    import lombok.SneakyThrows;
    import sun.misc.IOUtils;

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;

    public class MyClassLoader extends ClassLoader{

    private String path;
    
    public MyClassLoader(String path) {
        this.path = path;
    }
    
    @Override
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    //定义名称
        if (name.equals("xxx")){
            name = "
    

    name – The binary name of the class
    resolve – If true then resolve the class";
    }
    return super.loadClass(name, resolve);
    }

    //加载文件
    @SneakyThrows
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
    byte[] data = getClassData(path);
    return defineClass(name,getClassData(path),0,data.length);
    }

    byte[] getClassData(String path) throws IOException {
        FileInputStream fileInputStream = new FileInputStream(path);
        int length = fileInputStream.available();
        byte[] bytes = new byte[length];
        int read = fileInputStream.read(bytes);
        return bytes;
    }
    

    }

    ServiceLoader:

                ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
                Iterator<Driver> driversIterator = loadedDrivers.iterator();
    

    DriverManage是BootStrapCLassLoader加载进来。 com.xx.Driver是AppClassLoader加载进来的.

    但是SPI的类不是,

    DriverManager
    static { loadInitialDrivers(); println("JDBC DriverManager initialized"); } 收到加载范围限制,父类加载器需要委托子类加载器加载Class问价,这个时候就打破了双亲委派.
    各种服务商提供服,Java提供接口,这样就能提供替换,热部署。

    双亲委派只是建议,不是强制的

    相关文章

      网友评论

          本文标题:类加载,双亲委派

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