一直有一个疑问,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;
- }
- }