日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

java jdbc(mysql)驱动源码分析_JAVA JDBC(MySQL)驱动源码分析(二)

發布時間:2024/9/27 数据库 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java jdbc(mysql)驱动源码分析_JAVA JDBC(MySQL)驱动源码分析(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文系轉載,地址:http://blog.csdn.net/brilliancezhou/article/details/5425687

上一篇中分析了Class.forName(“com.mysql.jdbc.Driver”)幕后所做的事情,也就是在Driver實現類中的靜態塊和構造函數,本篇主要來分析一下靜態塊的一句代碼:DriverManager.registerDriver方法和其它相關的調用。

registerDriver方法是一個靜態方法,它所要做的工作就是加載所有系統提供的驅動,并把它們添加到具體的類中,形成對象。同時還創建連接,是一個管理驅動的工具類。如果我們使用的是mysql,那么加載的也就是它的驅動。

此方法的源碼如下:

publicstaticsynchronizedvoidregisterDriver(java.sql.Driver?driver)

throwsSQLException?{

if(!initialized)?{//1

initialize();

}

DriverInfo?di?=?newDriverInfo();

di.driver?=?driver;

di.driverClass?=?driver.getClass();

di.driverClassName?=?di.driverClass.getName();

//?Not?Required?--?drivers.addElement(di);

writeDrivers.addElement(di);

println("registerDriver:?"+?di);

/*?update?the?read?copy?of?drivers?vector?*/

readDrivers?=?(java.util.Vector)?writeDrivers.clone();

}

一、初始化操作

1、看看1處的代碼,判斷是否初始化,這個判斷的變量是一個靜態全局boolean值,初始為false

private static boolean initialized = false;

如果此變量的值為false那么它將會進入初始化方法,源碼如下:

staticvoidinitialize()?{

if(initialized)?{

return;

}

initialized?=?true;

loadInitialDrivers();

println("JDBC?DriverManager?initialized");

}

2、Initialize方法中判斷initialized值是否為真(其實就是通過此boolean變量判斷是否已經初始化完成),之后設置initialized值為true,接著又會調用另一個方法loadInitialDrivers() 同樣是靜態方法,用于調用系統類裝載器,裝載所有系統提供的驅動:

loadInitialDrivers()源碼:

privatestaticvoidloadInitialDrivers()?{

String?drivers;

try{

drivers?=?(String)?java.security.AccessController.doPrivileged(

newsun.security.action.GetPropertyAction("jdbc.drivers"));

}?catch(Exception?ex)?{

drivers?=?null;

}

//?If?the?driver?is?packaged?as?a?Service?Provider,

//?load?it.

//?Get?all?the?drivers?through?the?classloader

//?exposed?as?a?java.sql.Driver.class?service.

DriverService?ds?=?newDriverService();

//?Have?all?the?privileges?to?get?all?the

//?implementation?of?java.sql.Driver

java.security.AccessController.doPrivileged(ds);

println("DriverManager.initialize:?jdbc.drivers?=?"+?drivers);

if(drivers?==null)?{

return;

}

while(drivers.length()?!=0)?{

intx?=?drivers.indexOf(':');

String?driver;

if(x?<0)?{

driver?=?drivers;

drivers?=?"";

}?else{

driver?=?drivers.substring(0,?x);

drivers?=?drivers.substring(x+1);

}

if(driver.length()?==0)?{

continue;

}

try{

println("DriverManager.Initialize:?loading?"+?driver);

Class.forName(driver,?true,

ClassLoader.getSystemClassLoader());

}?catch(Exception?ex)?{

println("DriverManager.Initialize:?load?failed:?"+?ex);

}

}

}

主要代碼分析:

下面這段創建了一個內部類對象,創建此對象時,它會從系統服務中加載驅動

DriverService?ds?=newDriverService();

DriverService內部類的具體代碼:

classDriverServiceimplementsjava.security.PrivilegedAction?{

Iterator?ps?=?null;

publicDriverService()?{};

publicObject?run()?{

ps?=?Service.providers(java.sql.Driver.class);//從系統服務中加載驅動

try{

while(ps.hasNext())?{//遍歷驅動

ps.next();

}?//?end?while

}?catch(Throwable?t)?{

//?Do?nothing

}

returnnull;

}?//end?run

}?//end?DriverService

此句代碼就是找到所有的擁有權限的java.sql.Driver的實現

java.security.AccessController.doPrivileged(ds);

下面這段,意思是得到系統屬性jdbc.drivers對應驅動的驅動名稱,使用了JAVA的安全許可

drivers?=?(String)?java.security.AccessController.doPrivileged(

newsun.security.action.GetPropertyAction("jdbc.drivers"));

再看看后面的判斷和循環

首先判斷驅動服務對象是否為null,如果為null則返回,否則進入while循環,這個循環會依次遍歷多個數據庫驅動,因為jdbc:drivers會有多個數據庫驅動,驅動名是以:分割,接下來就是通過Class.forName依次裝載驅動類,在其中使用了ClassLoader.getSystemClassLoader()系統類裝載器。

if(drivers?==null)?{

return;

}

while(drivers.length()?!=0)?{

Class.forName(driver,?true,?ClassLoader.getSystemClassLoader());

}

上面分析的就是在registerDriver方法中所要做的第一件事情:初始化。可以看到initialize()做的工作就是裝載驅動,同時還需要使用到系統的一些功能。如: java.security.AccessController.doPrivileged,此方法允許在一個類實例中的代碼通知這個AccessController,它的代碼主體享受特權(Privileged),它不管這個請求是由什么代碼所引發的,只是單獨負責對它可得到的資源的訪問請求。比如說,一個調用者在調用doPrivileged方法時,可被標識為特權。AccessController做訪問控制決策時,如果checkPermission方法遇到一個通過doPrivileged方法調用而被視為特權調用者,那么checkPermission方法不會作許可檢查,表示那個訪問請求是被允許的,如果調用者沒有許可,則會拋出一個異常。

如:ClassLoader.getSystemClassLoader(),java中所有類都是通過ClassLoader裝載的,ClassLoader可以為java程序提供很好的動態特性,有必要去深入理解哦。

接下來再看初始化之后的代碼:

DriverInfo?di?=newDriverInfo();

di.driver?=?driver;

di.driverClass?=?driver.getClass();

di.driverClassName?=?di.driverClass.getName();

//?Not?Required?--?drivers.addElement(di);

writeDrivers.addElement(di);

println("registerDriver:?"+?di);

/*?update?the?read?copy?of?drivers?vector?*/

readDrivers?=?(java.util.Vector)?writeDrivers.clone();

創建DriverInfo對象

DriverInfo di = new DriverInfo();

DriverInfo驅動信息類,是一個內部類,

源碼如下:

classDriverInfo?{

Driver?????????driver;

Class??????????driverClass;

String?????????driverClassName;

publicString?toString()?{

return("driver[className="+?driverClassName?+","+?driver?+"]");

}

}

此類就是添加了三個屬性,分別表示驅動對象,驅動的Class對象,以及驅動的類名;同時重寫了toString方法。此內部類的作用就是以可以創建DriverInfo對象,以對象的形式保存驅動信息。

接下來就是設置對象的三個屬性:

DriverInfo?di?=newDriverInfo();

di.driver?=?driver;

di.driverClass?=?driver.getClass();

di.driverClassName?=?di.driverClass.getName();

然后添加到集合writeDrivers中,這個集合是Vector類型,定義為DriverManager的屬性

writeDrivers定義:

privatestaticjava.util.Vector?writeDrivers?=newjava.util.Vector();

驅動添加到集合

writeDrivers.addElement(di);

最后就是調用writeDrivers對象的clone方法

readDrivers?=?(java.util.Vector)?writeDrivers.clone();

readDrivers也是一個類型為Vector的集合,定義為DriverManager的屬性

privatestaticjava.util.Vector?readDrivers?=newjava.util.Vector();

為什么要先添加到writeDrivers然后再 clone到readDrivers中呢? writeDrivers和 readDrivers兩個都是驅動集合,無論是注冊驅動抑或是取消注冊,都是先對writeDrivers驅動集合中的數據進行添加或刪除,然后再把writeDrivers中的驅動都clone到readDrivers中,每次取出Driver并不是在writeDrivers中,而是在readDrivers中取得。那么這兩個驅動集合便可以這樣理解,writeDrivers驅動集合負責注冊驅動和注銷驅動,readDrivers驅動集合負責提供可用的驅動對象,readDrivers中的驅動對象應該都是可用的。把二者分開,使用者就不需加任何判斷,很方便。 這里又涉及到一個知識就是clone, 有興趣的朋友可以查看相關JAVA文檔,Thinking in java 中也有詳細描述。 這就是初始化的全過程,寫了這么多,實際上只做一件事情,就是完成所有驅動的加載。裝載之后就是連接了,在連載三當中我會詳細描述。

總結

以上是生活随笔為你收集整理的java jdbc(mysql)驱动源码分析_JAVA JDBC(MySQL)驱动源码分析(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。