【原创】关于class.forname

连接数据库前都要调用一下class.forname("driverName");然后使用DriverMnager获取连接,这是为什么呢?

首先jdbc标准要求,每个驱动必须向DriverManager注册一下,这样才能让其知道使用的什么驱动,因为jdbc统一了操作关系数据库的接口,程序员统一使用jdk中的接口调用相关方法实现功能,其中的多态调用就不详述了。为了能顺利连接并操作数据库,驱动必须向DriverManager注册才OK。

所以,Class.forName方法会加载该类,而加载类的时候,以oracle为例,oracle的oracle.jdbc.driver.OracleDriver类有个静态块:

 static
/*      */   {
/*  462 */     Timestamp localTimestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
/*      */     try
/*      */     {
/*  468 */       if (defaultDriver == null)
/*      */       {
/*  470 */         defaultDriver = new OracleDriver();
/*      */ 
/*  472 */         DriverManager.registerDriver(defaultDriver);
/*      */       }
/*      */ 
/*      */     }
/*      */     catch (RuntimeException localRuntimeException)
/*      */     {
/*      */     }
/*      */     catch (SQLException localSQLException)
/*      */     {
/*      */     }
/*      */ 
/* 1445 */     _Copyright_2004_Oracle_All_Rights_Reserved_ = null;
/*      */   }
/*      */ }

其中该行“DriverManager.registerDriver(defaultDriver);”就是注册,查看注册的代码:

 public static synchronized void registerDriver(java.sql.Driver driver)
    throws SQLException {
    if (!initialized) {
        initialize();
    }
      
    DriverInfo di = new DriverInfo();

    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();

    }

会先设置好驱动的class类型,class名称,Driver对象类型等等,以备后续获取连接等等使用。

可见,不一定非得class.forName,直接这样也可以:

defaultDriver = new OracleDriver();
DriverManager.registerDriver(defaultDriver);

只是通过class.forName可以直接加载并注册驱动程序。

看看spring的DriverManagerDataSource中,也是这么做的:

    public void setDriverClassName(String driverClassName) throws CannotGetJdbcConnectionException {
        if (!StringUtils.hasText(driverClassName)) {
            throw new IllegalArgumentException("driverClassName must not be empty");
        }
        this.driverClassName = driverClassName.trim();
        try {
            Class.forName(this.driverClassName, true, ClassUtils.getDefaultClassLoader());
        }
        catch (ClassNotFoundException ex) {
            throw new CannotGetJdbcConnectionException(
                    "Could not load JDBC driver class [" + this.driverClassName + "]", ex);
        }
        if (logger.isInfoEnabled()) {
            logger.info("Loaded JDBC driver: " + this.driverClassName);
        }
    }

 

posted on 2014-02-20 17:46  迷途@书童  阅读(269)  评论(0编辑  收藏  举报

导航