故事的开头还是从复习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()));
}