• 【JVM】MySQL驱动加载如何打破双亲委派机制


    上文根据MySQL中Driver加载相关内容介绍了Java中SPI机制,本文详细介绍驱动的加载如何打破了双亲委派机制
    Java双亲委派机制详细内容可以参考之前文章,在这里简单做个回顾

    原理

    首先我们要了解 Java 中的三层类加载器,分别为Bootstrap ClassLoader(启动类加载器),ExtClassLoader(扩展类加载器) 和 AppClassLoader(应用程序类加载器)。主要作用如下:
    Bootstrap ClassLoader(启动类加载器):负责加载 JRE 的核心类库,如 lib 下的 rt.jar 等等
    ExtClassLoader(扩展类加载器):主要加载 Java_Home/jre/lib/ext 目录下的类库
    AppClassLoader(应用程序类加载器):主要负责加载应用程序的主函数类

    那如果有一个我们写的Hello.java编译成的Hello.class文件,它是如何被加载到JVM中的呢?
    打开 IDEA 搜索“ClassLoader”,打开“java.lang”包下的 ClassLoader 类。找到 loadClass 方法

    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
    }
    
    protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException {
            // 首先,检查是否已经被类加载器加载过
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                try {
                    // 存在父加载器,递归的交由父加载器
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        // 直到最上面的Bootstrap类加载器
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }
    
                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    c = findClass(name);
                }
            }
            return c;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    DriverManager 中的 load

    参考 Java 中 SPI 理解那一章,我们查看静态代码块中的代码

    在这里插入图片描述

    点进 loadInitialDrivers 方法,看到如下内容:

    在这里插入图片描述

    那么此时就要想到一个问题,DriverManager 是属于 java.sql 包下的且全路径为 JAVA_HOME\jre\lib\rt.jar\java\sql。通过双亲委派机制可以知道,DriverManager 类已经被Bootstrap ClassLoader 已经加载了,此时就在这个类中进行操作了,按理说bootstrap classloader是无法加载到MySQL driver的(ClassNotFoundException)。那它为什么能调用 load 方法加载到对应驱动呢?也就是说,为什么 Bootstrap ClassLoader 类启动器中能使用到 AppClassLoader 类加载器?
    原因就在于会创建一个当前线程的AppClassLoader,打破了双亲委派加载机制,这也就是我们之前所说的线程上下文类加载器(ThreadContextClassLoader)

    在这里插入图片描述

  • 相关阅读:
    Springboot项目升级2.2.x升至2.7.x
    R语言生物群落(生态)数据统计分析与绘图教程
    如何进行lidar和imu的外参标定
    ORA-38824无法手工修改存储过程的问题
    vue实现单页面仿照购物车案例——基于mint-ui和vue2.0
    uniapp全局组件全局使用(不在每个页面template使用,仅支持H5),函数式调用全局组件方法
    A RANSOMWARE, HOW DO I RECOVER?
    【Windows】bat批处理程序简单应用
    linux EOF 用法
    Google Summer of Code谷歌编程之夏活动流程全解析(上)
  • 原文地址:https://blog.csdn.net/weixin_44078354/article/details/136259656