天天看點

關于Class.forName(“com.mysql.jdbc.Driver”)

原文位址為: 關于Class.forName(“com.mysql.jdbc.Driver”)

傳統的使用jdbc來通路資料庫的流程為:

Class.forName(“com.mysql.jdbc.Driver”);

String url = “jdbc:mysql://localhost:3306/test?user=root&password=123456″;

Connection con = DriverManager.getConnection(url);

Statement statement = con.createStatement();

最開始使用的時候,不明白為什麼首先要加載一個驅動類,之後就可以取得了Connection了,很好奇DriverManager是怎麼獲得那個驅動類的資訊,後來看了下com.mysql.jdbc.Driver這個類的源代碼,豁然開朗了。原來在com.mysql.jdbc.Driver類中有這麼一段靜态初始化代碼:

static {

try {

java.sql.DriverManager.registerDriver(new Driver());

} catch (SQLException E) {

throw new RuntimeException(“Can’t register driver!”);

}

}

也就是,在Class.forName加載完驅動類,開始執行靜态初始化代碼時,會自動建立一個Driver的對象,并調用DriverManager.registerDriver把自己注冊到DriverManager中去。

ps1: Class.forName(String) 與ClassLoader.loadClass(String)的差別

Class.forName(String): 加載類,并且執行類初始化;可以通過Class.forName(String, boolean, ClassLoader)第二個參數來僅僅加載類不執行初始化;

ClassLoader.loadClass(String): 僅僅加載類,不執行類初始化;

ps2: 有時會看到這種用法:

Class.forName(“com.mysql.jdbc.Driver”).newInstance();

這是沒有必要的,正如前述,靜态初始化已經new了一個Driver的對象,注冊到DriverManager中去,在此再建立一個Driver對象則是完全沒有必要的,浪費空間。

ps3: 結合ps1,Class.forName(“com.mysql.jdbc.Driver”);相當于:

ClassLoader loader = Thread.currentThread().getContextClassLoader();

Class cls = loader.loadClass(“com.mysql.jdbc.Driver”);

cls.newInstance();

這種方法的問題同ps2, 浪費了一個Driver對象;

ps4: 在java 6中,引入了service provider的概念,即可以在配置檔案中配置service(可能是一個interface或者abstract class)的provider(即service的實作類)。配置路徑是:/META-INF/services/下面。詳細資訊見:http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider

而java.sql.DriverManager也添加了對此的支援,是以,在JDK6中,DriverManager的查找Driver的範圍為:

1)system property “jdbc.drivers” 中配置的Driver值;

2)使用者調用Class.forName()注冊的Driver

3)service provider配置檔案java.sql.Driver中配置的Driver值。

是以,在jdk6中,其實是可以不用調用Class.forName來加載mysql驅動的,因為mysql的驅動程式jar包中已經包含了java.sql.Driver配置檔案,并在檔案中添加了com.mysql.jdbc.Driver.但在JDK6之前版本,還是要調用這個方法。

參考文檔:

1)http://docs.oracle.com/javase/1.5.0/docs/api/java/sql/DriverManager.html

2)http://docs.oracle.com/javase/6/docs/api/index.html?java/sql/DriverManager.html

3)http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider

轉載請注明本文位址: 關于Class.forName(“com.mysql.jdbc.Driver”)