Class.forName(String name)java
接上一篇JDBC。原本這個內容是放在前面的一篇裏面的一塊兒的,後來發現越寫越多,想一想看就算了,仍是單獨開一篇文章好了,這樣也能寫得更加詳細點。mysql
上一篇文章的第4點,getConnection()方法裏面,我把從.properties裏面獲取mysqlpackage的地方替換成實際的value值,那麼替換後的應該是Class.forName("com.mysql.jdbc.Driver"),實際上全部的JDBC鏈接先寫的基本上也都是這一句。另外,哪怕刪除這一句,也是能夠運行成功的。那爲何還要Class.forName("com.mysql.jdbc.Driver")呢?OK,分點講解。算法
爲何要Class.forName("com.mysql.jdbc.Driver")?sql
JDBC是23種模式中的橋接模式的典型應用,熟悉橋接模式的基本上稍微看一下源代碼就知道爲何了,那橋接模式這裏不講,只講爲何要這麼作。Class.forName(String className)的做用有兩個,第一是CLASSPATH下指定名字的.class文件加載到Java虛擬機內存中, 第二是初始化這個類。看到這句話,返回值都沒有,那寫在這裏的做用很明顯了,就是初始化"com.mysql.jdbc.Drvier"。初始化作了什麼?給靜態資源賦值以及執行靜態代碼塊,因此,反編譯一下"mysql-connector-java-5.1.20-bin.jar"這個jar包,查看一下Driver類:數據庫
public class Driver extends NonRegisteringDriver
implements java.sql.Driver { public Driver() throws SQLException { } static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } } }
看到Class.forName("com.mysql.jdbc.Driver")的做用實際上就是調用DriverManager的registerDriver方法註冊一個mysql的JDBC驅動(Driver)而已,Driver繼承NonRegisteringDriver.java,NonRegisteringDriver.java實現了JDK提供的Driver接口,這個Driver提供了若干數據庫鏈接的方法,每一個不一樣的數據庫鏈接類都必須實現它,並重寫和具體的數據庫鏈接的算法。DriverManager也是JDK中的類,截一些關鍵代碼:數組
private static final CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList();
public static synchronized void registerDriver(Driver paramDriver) throws SQLException { if (paramDriver != null) registeredDrivers.addIfAbsent(new DriverInfo(paramDriver)); else throw new NullPointerException(); println("registerDriver: " + paramDriver); }
底層利用了一個CopyOnWriteArrayList做爲容器(這是一個線程安全的容器,不過每次add的時候都會對底層數組進行一次新的複製,因此在讀遠多於寫的時候建議可使用這個),放那些註冊進去的DriverInfo。最終getConnection(...)的時候就拿registerDrivers裏面註冊進去的具體的某個數據庫的DriverInfo(像MySql的Driver就在DriverInfo裏面)去鏈接具體的數據庫。OK,因此總結一下整個流程:安全
JDK不負責和數據庫鏈接打交道,也不必,只提供一個具體的接口Driver,告訴全部第三方,要鏈接數據庫,就去實現這個接口,而後經過DriverManager註冊一下,到時候鏈接某個數據庫的時候,你已經在我這裏註冊了,我會調用你註冊進來的Driver裏面的方法去對指定數據庫進行鏈接的。而後Mysql就實現本身的Driver,Oracle就實現本身的Driver,經過static塊註冊一下,再而後,就沒有而後了。spa
爲何不直接new?線程
意思是這麼寫"com.mysql.jdbc.Driver d = new com.mysql.jdbc.Driver();",能夠啊,由於在new的時候會自動觸發對一個類的初始化。問題是new出來幹嗎?com.mysql.jdbc.Driver裏面的方法咱們會用到嗎,而且咱們知道怎麼用嗎?僅僅爲了初始化一個類而new一個類實例出來還不如不去new,直接使用Class.forName(String name)初始化就能夠了。DriverManager類的getConnection(...)方法的存在自己就是幫助用戶調用Driver裏面的各類方法鏈接數據庫,JDK都作好了,開發者就不必本身寫了。code
爲何刪除Class.forName("com.mysql.jdbc.Driver")仍是能夠運行?
1996年1月23日JDK1.0發佈,Java語言有了第一個正式版本的運行環境。JDBC是1997年2月19日,在JDK1.1的版本中發佈的,從版本就看得出,JDBC屬於Java技術的一些最基礎的功能點。那在JDK1.5以後,其實已經不須要去顯式調用Class.forName("com.mysql.jdbc.Driver")了,DriverManager會自動去加載合適的驅動,可是前提是CLASSPATH下必須有驅動jar包。