JDBC驱动类加载



1. 加载数据库启动代码:
    Class.forName("com.mysql.jdbc.Driver")
    Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.108.145/test", "root", "root");
    Class.forName 方法会根据类的全路径名称去加载对应的class文件,生成类型,并初始化类型。也就是说static语句块会执行。
2.查看
com.mysql.jdbc.Driver 
   public class Driver extends NonRegisteringDriver implements java.sql.Driver {
     // ~ Static fields/initializers
     // ---------------------------------------------
     //
     // Register ourselves with the DriverManager
     //
     static {
          try {
              java.sql.DriverManager.registerDriver(new Driver());
          } catch (SQLException E) {
              throw new RuntimeException("Can't register driver!");
          }
     }
     // ~ Constructors
     // -----------------------------------------------------------
     /**
      * Construct a new driver and register it with DriverManager
      *
      * @throws SQLException
      *             if a database error occurs.
      */
     public Driver() throws SQLException {
          // Required for Class.forName().newInstance()
     }
}


static语句块就做了一件事:生成驱动实例,并向DriverManager注册。所谓注册,就是将driver的信息保存起来,以便后来取用。


3查看DriverManager类
Class.forName(“com.mysql.jdbc.Driver”)是 强制JVM将com.mysql.jdbc.Driver这个类加载入内存,并将其注册到DriverManager类,然后根据DriverManager.getConnection(url,user,pwd)中的url找到相应的驱动类,最后调用该该驱动类的connect(url, info)来获得connection对象。
而DriverManager也在这个时候被加载了,根据ClassLoader的双亲委托机制,DriverManager由bootstrap ClassLoader加载;
因为DriverManager在rt.jar里面,它的类加载器上启动类加载器。而数据库的driver(com.mysql.jdbc.Driver)是放在classpath里面的,启动类加载器是不能加载的。所以,如果严格按照双亲委派模型,是没办法解决的。而这里的解决办法是:通过调用类的类加载器去加载。而如果调用类的加载器是null,就设置为线程的上下文类加载器:
Thread.currentThread().getContextClassLoader()


com.mysql.jdbc.Driver实际被加载了两次:第一次是在Class.forName(“com.mysql.jdbc.Driver”)时,第二次就是在isDriverAllowed中,破坏双亲模式就是在这个位置。
    private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
        boolean result = false;
        if(driver != null) {
            Class<?> aClass = null;
            try {
                aClass =  Class.forName(driver.getClass().getName(), true, classLoader);
            } catch (Exception ex) {
                result = false;
            }
             result = ( aClass == driver.getClass() ) ? true : false;
        }
        return result;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值