20200227——class.forName()做了什么

故事的开头还是从复习mybatis开始,说到mybatis就想到了古老的JDBC
那就有这段代码了

Class.forName("com.mysql.jdbc.Driver")

那么到底做了什么

首先我们知道Class.forName() 方法要求JVM查找并加载指定的类到内存中,此时将"com.mysql.jdbc.Driver" 当做参数传入,就是告诉JVM,去"com.mysql.jdbc"这个路径下找Driver类,将其加载到内存中。

由于加载类文件时会执行其中的静态代码块,其中Driver类的源码如下

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());//首先new一个Driver对象,并将它注册到DriverManage中
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

接下来我们再看看这个DriverManager.registerDriver 方法

    public static synchronized void registerDriver(java.sql.Driver driver)
        throws SQLException {

        registerDriver(driver, null);
    }

继续看这个registerDriver(driver, null) 方法

private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();// registeredDrivers 是一个支持并发的arraylist
......
public static void registerDriver(java.sql.Driver driver, DriverAction da)
        throws SQLException {
        if (driver != null) {
            //如果该驱动尚未注册,那么将他添加到 registeredDrivers 中去。这是一个支持并发情况的特殊ArrayList
            registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
        } else {
            // This is for compatibility with the original DriverManager
            throw new NullPointerException();
        }
        println("registerDriver: " + driver);
    }

此时,Class.forName(“com.mysql.jdbc.Driver”) 的工作就完成了,工作就是:将mysql驱动注册到DriverManager中去。接下来我们看是怎么进行调用的

DriverManager.getConnection方法分析

注册到DriverManager中之后,我们就可以通过DriverManager的getConnection方法获得mysql的连接了:

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");

个人理解在这里插入代码片

class.forName(“com.mysql.jdbc.Driver”)
是JVM加载这个类
加载类的过程中,就执行了这个类的静态代码

 static {
        try {
        	//1. 新建一个mysql的driver对象
        	//2. 将这个对象注册到DriverManager中
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }

静态代码段执行了DriverManager.registerDriver(new Driver())这个方法

这个方法返回自身调用方法

public static void registerDriver(java.sql.Driver driver) throws SQLException {
		//它实际调用了自身的registerDriver方法
        registerDriver(driver, null);
    }

registerDriver(driver, null);方法

public static void registerDriver(java.sql.Driver driver, DriverAction da)
        throws SQLException {

        /* Register the driver if it has not already been added to our list */
        if (driver != null) {
        	//如果该驱动尚未注册,那么将他添加到 registeredDrivers 中去。这是一个支持并发情况的特殊ArrayList
            registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
        } else {
            // This is for compatibility with the original DriverManager
            throw new NullPointerException();
        }

        println("registerDriver: " + driver);

    }

registeredDrivers.addIfAbsent(new DriverInfo(driver, da)) 表示:如果该驱动尚未注册,那么将他添加到 registeredDrivers 这个并发链表中去中去。CopyOnWriteArrayList。

DriverManager类的源码

    private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();

所以所谓的class.forName 就是把com.mysql.jdbc中的一个Driver实例注册到了DriverManager中的属性registeredDrivers ,是一个ArrayList列表

之后就是调用getConnection

public static Connection getConnection(String url)
        throws SQLException {

        java.util.Properties info = new java.util.Properties();
        return (getConnection(url, info, Reflection.getCallerClass()));
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值