mysql驱动为什么自动加载_为什么JDBC中加载驱动要使用反射?
原文鏈接:https://www.cnblogs.com/homejim/p/8076481.html
在JDBC詳解系列(一)之流程中,我將數(shù)據(jù)庫(kù)的連接分解成了六個(gè)步驟。
JDBC流程:
第一步:加載Driver類,注冊(cè)數(shù)據(jù)庫(kù)驅(qū)動(dòng);
第二步:通過(guò)DriverManager,使用url,用戶名和密碼建立連接(Connection);
第三步:通過(guò)Connection,使用sql語(yǔ)句打開(kāi)Statement對(duì)象;
第四步:執(zhí)行語(yǔ)句,將結(jié)果返回resultSet;
第五步:對(duì)結(jié)果resultSet進(jìn)行處理;
第六步:倒序釋放資源resultSet-》preparedStatement-》connection。
接著將第一步的加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)講解一下。加載驅(qū)動(dòng)就是這一句代碼啦:
public static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
Class.forName(JDBC_DRIVER);
//以上也可以直接替換為 new com.mysql.jdbc.Driver();
Class.forName(String className)返回的是一個(gè)類,在這個(gè)過(guò)程中,會(huì)把該類加載到j(luò)vm中,即這個(gè)類的靜態(tài)代碼會(huì)執(zhí)行,我們主要就是為了要個(gè)靜態(tài)代碼塊(java.sql.DriverManager.registerDriver(new Driver());)執(zhí)行才加載這個(gè)驅(qū)動(dòng)的。為什么不使用new com.mysql.jdbc.Driver()這種方式呢?
如果使用new com.mysql.jdbc.Driver()這種方式,會(huì)對(duì)這個(gè)具體的類產(chǎn)生依賴。后續(xù)如果你要更換數(shù)據(jù)庫(kù)驅(qū)動(dòng),就得重新修改代碼。而使用反射的方式,只需要在配置文件中,更改相應(yīng)的驅(qū)動(dòng)和url即可。----解耦
加載驅(qū)動(dòng)的過(guò)程中,發(fā)生了什么?我們來(lái)看一下mysql的驅(qū)動(dòng)類代碼。
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
//
// Register ourselves with the DriverManager
//
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
/**
* Construct a new driver and register it with DriverManager
*
* @throws SQLException
* if a database error occurs.
*/
public Driver() throws SQLException {
// Required for Class.forName().newInstance()
}
ok,就是說(shuō)其實(shí)起作用的是這一句代碼:
java.sql.DriverManager.registerDriver(new Driver());
查看了一下registerDriver的源碼,大致是如果DriverManager中沒(méi)有這個(gè)類,就將這個(gè)類添加到到DriverManager的list中。在實(shí)際的使用過(guò)程中,我們完全可以用上面這一句代碼將以反射加載驅(qū)動(dòng)的方式替換掉,但也會(huì)對(duì)具體的類產(chǎn)生依賴,導(dǎo)致后續(xù)更改不便。
到此,我想測(cè)試一下把加載驅(qū)動(dòng)的代碼去掉,然后看會(huì)報(bào)什么錯(cuò)誤。結(jié)果竟然沒(méi)問(wèn)題。這是在逗我嗎?書(shū)里面不是這么教的。只能進(jìn)行g(shù)oogle了,原因如下:
JDBC4.0以后新增了新特性:JDBC4.0不再需要顯式調(diào)用class.forName()注冊(cè)驅(qū)動(dòng),DriverManager初始化中會(huì)通過(guò)ServiceLoader類,在我們classpath中jar(數(shù)據(jù)庫(kù)驅(qū)動(dòng)包)中查找,使用META-INF\services\java.sql.Driver文本中的類名稱去注冊(cè)。
也就說(shuō),在啟動(dòng)的時(shí)候,通過(guò)jar包下面的java.sql.Driver里的文本內(nèi)容,幫你把驅(qū)動(dòng)給加載了。
OK,明白了這個(gè)之后,我將mysql驅(qū)動(dòng)jar包中java.sql.Driver中的文本內(nèi)容刪除了,然后就將Class.forName(JDBC_DRIVER)注釋掉,果然報(bào)錯(cuò)了:
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/jdbc_test
總結(jié)
以上是生活随笔為你收集整理的mysql驱动为什么自动加载_为什么JDBC中加载驱动要使用反射?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: jetty java web_i-jet
- 下一篇: META-INF目录是干啥用的?