一直有一個疑問,Class.forName(driverName)是如何完成載入資料庫驅動的,查閱了Oracle驅動的原始碼之後,大體弄清楚了。
我們知道,Class.forName所做的工作是載入指定的class檔案到java虛擬機器的記憶體,載入class檔案到記憶體的時候,該class檔案的靜態變數和靜態初始化塊是要執行的,玄機即在此。
看Oracle資料庫的驅動程式碼:
private static OracleDriver defaultDriver = null;
static
{
try
{
if (defaultDriver == null)
- {
- defaultDriver = new oracle.jdbc.OracleDriver();
- DriverManager.registerDriver(defaultDriver);
- }
- AccessController.doPrivileged(new PrivilegedAction()
- {
- public Object run()
- {
- OracleDriver.registerMBeans();
- return null;
- }
- });
- Timestamp localTimestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
- }
- catch (SQLException localSQLException)
- {
- Logger.getLogger("oracle.jdbc.driver").log(Level.SEVERE, "SQLException in static block.", localSQLException);
- }
- catch (RuntimeException localRuntimeException1)
- {
- Logger.getLogger("oracle.jdbc.driver").log(Level.SEVERE, "RuntimeException in static block.", localRuntimeException1);
- }
- try
- {
- Class localClass = Class.forName("oracle.security.pki.OraclePKIProvider");
- Object localObject = localClass.newInstance();
- }
- catch (RuntimeException localRuntimeException2)
- {
- }
- catch (Exception localException)
- {
- }
- catch (NoClassDefFoundError localNoClassDefFoundError)
- {
- }
- catch (Error localError)
- {
- }
- catch (Throwable localThrowable)
- {
- }
- systemTypeMap = new Hashtable(3);
- try
- {
- systemTypeMap.put("SYS.XMLTYPE", Class.forName("oracle.xdb.XMLTypeFactory"));
- }
- catch (ClassNotFoundException localClassNotFoundException1)
- {
- }
- try
- {
- systemTypeMap.put("SYS.ANYTYPE", Class.forName("oracle.sql.AnyDataFactory"));
- systemTypeMap.put("SYS.ANYDATA", Class.forName("oracle.sql.TypeDescriptorFactory"));
- }
- catch (ClassNotFoundException localClassNotFoundException2)
- {
- }
- _Copyright_2007_Oracle_All_Rights_Reserved_ = null;
- }
private static OracleDriver defaultDriver = null;
static
{
try
{
if (defaultDriver == null)
{
defaultDriver = new oracle.jdbc.OracleDriver();
DriverManager.registerDriver(defaultDriver);
}
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
OracleDriver.registerMBeans();
return null;
}
});
Timestamp localTimestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
}
catch (SQLException localSQLException)
{
Logger.getLogger("oracle.jdbc.driver").log(Level.SEVERE, "SQLException in static block.", localSQLException);
}
catch (RuntimeException localRuntimeException1)
{
Logger.getLogger("oracle.jdbc.driver").log(Level.SEVERE, "RuntimeException in static block.", localRuntimeException1);
}
try
{
Class localClass = Class.forName("oracle.security.pki.OraclePKIProvider");
Object localObject = localClass.newInstance();
}
catch (RuntimeException localRuntimeException2)
{
}
catch (Exception localException)
{
}
catch (NoClassDefFoundError localNoClassDefFoundError)
{
}
catch (Error localError)
{
}
catch (Throwable localThrowable)
{
}
systemTypeMap = new Hashtable(3);
try
{
systemTypeMap.put("SYS.XMLTYPE", Class.forName("oracle.xdb.XMLTypeFactory"));
}
catch (ClassNotFoundException localClassNotFoundException1)
{
}
try
{
systemTypeMap.put("SYS.ANYTYPE", Class.forName("oracle.sql.AnyDataFactory"));
systemTypeMap.put("SYS.ANYDATA", Class.forName("oracle.sql.TypeDescriptorFactory"));
}
catch (ClassNotFoundException localClassNotFoundException2)
{
}
_Copyright_2007_Oracle_All_Rights_Reserved_ = null;
}
由上面的程式碼可以看出,在通過Class.forName載入oracle驅動的時候,在靜態初始化塊中,會完成驅動的註冊工作,即建立驅動類的例項,並把例項註冊給驅動管理器DriverManager,核心程式碼如下:
- if (defaultDriver == null)
- {
- defaultDriver = new oracle.jdbc.OracleDriver();
- DriverManager.registerDriver(defaultDriver);
- }
if (defaultDriver == null)
{
defaultDriver = new oracle.jdbc.OracleDriver();
DriverManager.registerDriver(defaultDriver);
}
如此之後,就不能理解,接下來就可以從驅動管理器中獲得到資料庫的連線了,如:
- public class ConnectionTool {
- static String url = "jdbc:oracle:thin:@10.10.10.100:1521:loushang";
- static String driverName = "oracle.jdbc.driver.OracleDriver";
- public static Connection getCon(){
- try {
- Class.forName(driverName);
- return DriverManager.getConnection(url, "apitest", "apitest");
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- return null;
- }
- }