一句话总结:将mysql驱动注册到DriverManager中去。
那么为什么可以通过这行代码实现注册driver功能呢?
答:
我们首先看forName方法的源码:
public static Class> forName(String className) throws ClassNotFoundException {
Class> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
我们可以看到返回值是 Class>,即我们将mysql的驱动类→driver类加载到了
内存中。
我们知道,当类被加载到内存中时,会首先执行类的静态代码块中的内容,那我们接下来就看看Driver类的源码,看看它被加载到内存中时,到底执行了什么内容。
我们找到com.mysql.jdbc.Driver类:
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
//1. 新建一个mysql的driver对象
//2. 将这个对象注册到DriverManager中
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
可以看到,静态代码块中执行的内容是:新建一个msql的driver对象,并将其注册到DriverManager中去。
接下来我们再看看这个DriverManager.registerDriver 方法,先看这个方法的说明:
/**
* Registers the given driver with the {@code DriverManager}.
* A newly-loaded driver class should call
* the method {@code registerDriver} to make itself
* known to the {@code DriverManager}. If the driver is currently
* registered, no action is taken.
*/
public static void registerDriver(java.sql.Driver driver) throws SQLException {
//它实际调用了自身的registerDriver方法
registerDriver(driver, null);
}
继续看这个registerDriver(driver, null);方法
// registeredDrivers 是一个支持并发的arraylist
private final static CopyOnWriteArrayList registeredDrivers = new CopyOnWriteArrayList<>();
......
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。
此时,Class.forName(“com.mysql.jdbc.Driver”) 的工作就完成了,这一行代码的工作就是:将mysql驱动注册到DriverManager中去
注册的DriverManager中之后,我们就可以 通过DriverManager的getConnection方法获得mysql的连接了:
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");
接下来我们在看看这个getConnection方法:
@CallerSensitive
public static Connection getConnection(String url,
String user, String password) throws SQLException {
......
return (getConnection(url, info, Reflection.getCallerClass()));
}
同样,调用了自身的 getConnection方法;继续往里看
private static Connection getConnection(
String url, java.util.Properties info, Class> caller) throws SQLException {
......
for (DriverInfo aDriver : registeredDrivers) {
......
Connection con = aDriver.driver.connect(url, info);
......
}
}
可以看到它对上文提到的特殊ArrayList进行了遍历,调用了connect(url, info); 方法,这是一个接口,由各个不同的驱动自己实现。
/**
* Attempts to make a database connection to the given URL.
* The driver should return "null" if it realizes it is the wrong kind
* of driver to connect to the given URL. This will be common, as when
* the JDBC driver manager is asked to connect to a given URL it passes
* the URL to each loaded driver in turn.
*/
Connection connect(String url, java.util.Properties info)
throws SQLException;
到此为止,我们就获得了connection对象,现在就可以对数据库进行操作了。