Mysql JDBC驱动源码分析(加载驱动)一
2016-03-10 10:06
323 查看
一、jdbc连接驱动器的注册加载
Class.forName("com.mysql.jdbc.Driver");当以上类被装载时执行以下程序
package com.mysql.jdbc; import java.sql.SQLException; public class Driver extends NonRegisteringDriver implements java.sql.Driver { //执行这个静态代码块 static { try {//注册mysql实现的驱动类 java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } } public Driver() throws SQLException { // Required for Class.forName().newInstance() } }进入java.sql.DriverManager.registerDirver(new Driver());中的功能实现
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); /* 用于读取驱动的集合 */ readDrivers = (java.util.Vector) writeDrivers.clone(); //用以上两个集合达到读写分离的状态,由 Vector 的 iterator 和 listIterator 方法所返回的迭代器是 快速失败的
二、驱动器的初始化操作
static void initialize() { if (initialized) { return; } //private static boolean initialized = false;静态全局变量,只初始化一次 initialized = true; loadInitialDrivers(); println("JDBC DriverManager initialized"); }实现初始化操作
private static void loadInitialDrivers() { String drivers; try {//得到系统属性jdbc.drivers对应驱动的驱动名称,使用了JAVA的安全许可 drivers = (String) java.security.AccessController.doPrivileged( new sun.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 = new DriverService(); // 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) { int x = 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 = new DriverService(); 代码如下: class DriverService implements java.security.PrivilegedAction { Iterator ps = null; public DriverService() {}; public Object run() { //从系统服务中加载驱动 ps = Service.providers(java.sql.Driver.class); /* Load these drivers, so that they can be instantiated. * It may be the case that the driver class may not be there * i.e. there may be a packaged driver with the service class * as implementation of java.sql.Driver but the actual class * may be missing. In that case a sun.misc.ServiceConfigurationError * will be thrown at runtime by the VM trying to locate * and load the service. * * Adding a try catch block to catch those runtime errors * if driver not available in classpath but it's * packaged as service and that service is there in classpath. */ try { while (ps.hasNext()) { ps.next();//遍历所有的驱动 } // end while } catch(Throwable t) { // Do nothing } return null; } //end run }
//使用特权去获取ds java.security.AccessController.doPrivileged(ds);
相关文章推荐
- Mysql时间戳转换函数
- Mysql:is not allowed to connect to this MySQL server
- mysql中 show table status 获取表信息
- mysql小结
- Mysql group by 排序问题
- mysql错误解决总结
- 如果公司里有上百个表要做触发器,如果手动写代码的话。很累,所以今天写了一个小程序,自动生成mysql的触发代码。
- MYSQL 导入出错问题
- 关于mysql数据库备份的一些选项和参数
- windows下安装并配置mysql解压版
- mysql存储引擎myisam和innodb的区别
- 关于mysql和pgsql中一些常用的函数
- mysql-bin.000 二进制文件
- Windows下搭建MySql Master-Master Replication
- Mysql中 show table status 获取表信息的方法
- Mysql性能优化案例研究-覆盖索引和SQL_NO_CACHE
- Mysql性能优化案例 - 覆盖索引分享
- 简单解决Windows中MySQL的中文乱码与服务启动问题
- MySQL安装笔记
- Navicat for MySQL 11注册码获取方法介绍