美文网首页mysql面试
Java链接MySQL——JDBC对双亲委派模型的破坏

Java链接MySQL——JDBC对双亲委派模型的破坏

作者: 雁阵惊寒_zhn | 来源:发表于2021-12-04 16:58 被阅读0次

    JDBC链接MySQL的代码片段和执行结果

    Java15和JDBC 8.0.18

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.18</version>
    </dependency>
    
    public void driverTest() throws SQLException {
            System.out.println(java.sql.Driver.class.getClassLoader());
            System.out.println(java.sql.DriverManager.class.getClassLoader());
            System.out.println(com.mysql.jdbc.Driver.class.getClassLoader());
            Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306", "root", "123456");
    }
    

    System.out.println打印的结果

    jdk.internal.loader.ClassLoaders$PlatformClassLoader@48140564
    jdk.internal.loader.ClassLoaders$PlatformClassLoader@48140564
    jdk.internal.loader.ClassLoaders$AppClassLoader@55054057
    

    上面System.out.println打印的结果很容易理解,com.mysql.jdbc.Driver是第三方提供的依赖由AppClassLoader加载,其父类java.sql.Driver是JDK自带模块被PlatformClassLoader加载。java.sql.DriverManage与java.sql.Driver相同。

    注:JDK9之后用PlatformClassLoader代替ExtClassLoader加载器,用来加载JDK中的非核心模块类。

    如何破坏双亲委派模型

    深入DriverManager.getConnection源码


    getConnection源码

    Debug代码,其中参数caller结果如下,是我们自定义调用DriverManager.getConnection的方法driverTest()的类。而这个自定义类的ClassLoader显然是AppClassLoader。


    那么,继续往下执行时,callerCL会被赋值为AppClassLoader。if语句不会走到,之后注册的所有数据库Driver都是基于callerCL来加载。



    接下来分析如何破坏双亲委派模型:

    1. AppClassLoader加载我们定义的测试类DriverStudy;
    2. 调用DriverManager.getConnection时,委派给其父加载器PlatformClassLoader加载;
    3. getConnection中尝试去加载第三方依赖的数据库Driver时,我们发现没有使用此方法所在类的加载器PlatformClassLoader(因为类加载机制制约,PlatformClassLoader也无法加载第三方类库),而是通过参数传入了测试类DriverStudy的加载器AppClassLoader,另外if语句的条件判断也保证一旦callerCL为null(证明是BootClassLoader)或为PlatformClassLoader时,会被设置为上下文类加载器。
    callerCL = Thread.currentThread().getContextClassLoader()。
    
    1. 上下文类加载器Debug显示如下为AppClassLoader。上下文类加载器顾名思义典型应用就是被线程设置后加载应用,可通过Thread.setContextClassLoaser()方法设置。


    总结一下,PlatformClassLoader加载DriverManager,执行getConnection方法后,会显示的找到PlatformClassLoader的子加载器AppClassLoader去加载第三方的依赖类。父加载器调用子加载器进行类的加载,这里打破了双亲委派模型。

    相关文章

      网友评论

        本文标题:Java链接MySQL——JDBC对双亲委派模型的破坏

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