【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 方法

java 复制代码
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;
}

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)

相关推荐
韩楚风9 小时前
【参天引擎】事务生命周期 / MVCC / Undo / ACID / 分布式事务 功能域整体解析
数据库·分布式·mysql·架构·cantian
愿做无知一猿10 小时前
Nacos连接MySQL异常?DataGrip竟成救星
数据库·mysql
G.O.G.O.G10 小时前
LeetCode SQL 从入门到精通(MySQL)06(上)
数据库·sql·mysql·leetcode
千桐科技10 小时前
qData 数据中台开源版从 MySQL 到 Doris完成一次数据同步
大数据·mysql·开源·doris·数据中台·qdata
Omics Pro12 小时前
深度学习多组学互作:组内+组间
数据库·人工智能·深度学习·mysql·搜索引擎·自然语言处理
残*影13 小时前
如何优雅地保存MySQL数据变更历史?
数据库·mysql
Database_Cool_14 小时前
数据仓库弹性扩缩容怎么实现?AnalyticDB MySQL 在线扩容 0 中断实战
数据库·数据仓库·mysql·阿里云
orient15 小时前
JVM 调优实战:从监控告警到参数配置,一套完整方法论
jvm
orient15 小时前
大白话 JVM:对象到底存在哪?GC 又是怎么运行的?
jvm
炸薯条!15 小时前
从零开始学C++ (内存管理)
java·jvm·c++