Class.forName和registerDriver的区别
我们都知道JDBC的代码怎么写,比如以MySQL JDBC为例
//注册JDBC驱动
Class.forName("com.mysql.jdbc.Driver"); //然后就可以拿到JDB的连接
DriverManager.getConnection("jdbc:mysql://localhost/quickstart", "root", "!123456");
通过阅读MySQL JDBC的 源代码,本文将讲述这两段代码背后的内容
1. Class.forName做了什么?
2. java.sql.DriverManager.registerDriver(new Driver())做了什么?
下面详细介绍
1. Class.forName做了什么?
使用Class.forName()会将调用的类初始化,即调用class中的static块,并返回该类的Class对象。比如: com.mysql.jdbc.Driver中代码,当调用Class.forName(“com.mysql.jdbc.Driver”)时,Driver类中static部分就会被调用。

static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}

2. java.sql.DriverManager.registerDriver(new Driver())做了什么?
在开始介绍之前先说明2点
(1) com.mysql.jdbc.Driver 的构造函数new Driver()是空的。
(2) 给DriverManager设置一个LogWriter, 可以看到更多log信, DriverManager.setLogWriter(new java.io.PrintWriter(System.out));
其实registerDriver方法做的事情很简单, registerDriver先初始化自己,然后将Driver实例添加到DriverManager中的2个Vector中:readDrivers, writeDrivers
3. DriverManager.getConnection做了什么?
遍历readDrivers, 找到合适的JDBC Driver然后调用其connect方法得到连接,具体怎么得到的连接,我们下一篇文章中将介绍。
下面通过两个例子说明这两个接口
例子1:查看DriverManager.getConnection()log
比如我注册了两个Driver, 一个是Sybase的JDBC Driver,一个是MySQL的JDBC Driver
Class.forName("com.sybase.jdbc2.jdbc.SybDriver");
Class.forName("com.mysql.jdbc.Driver");
DriverManager.getConnection("jdbc:mysql://localhost/quickstart", "root", "!QAZxsw2");
运行这段代码,你可以看到如下log (记得在这段代码前设置LogWriter, DriverManager.setLogWriter(new java.io.PrintWriter(System.out));)
static init
DriverManager.initialize: jdbc.drivers = null
JDBC DriverManager initialized
registerDriver: driver[className=com.sybase.jdbc2.jdbc.SybDriver,com.sybase.jdbc2.jdbc.SybDriver@42e816]
registerDriver: driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@de6ced]
java.sql.DriverManager.registerDriver(new Driver())
DriverManager.getConnection("jdbc:mysql://localhost/quickstart")
trying driver[className=com.sybase.jdbc2.jdbc.SybDriver,com.sybase.jdbc2.jdbc.SybDriver@42e816]
trying driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@de6ced] //遍历每个注册过得Driver,这里MySQL Driver在第二个,所以第二次才成功
getConnection returning driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@de6ced]
例子2:实现自己的JDBC 驱动
写一个MyDriver.java类,实现java.sql.Driver接口, MyConnection.java类,实现java.sql.Connection(1)在MyDriver.java中,类似com.mysql.jdbc.Driver中的static{}代码,注册自己
(2)并实现自己的acceptUrl,定义你的JDBC URL格式
//TODO,代码在另一台机器上,下次贴上。
运行以后,可以看到如下log信息
static init
DriverManager.initialize: jdbc.drivers = null
JDBC DriverManager initialized
registerDriver: driver[className=com.sybase.jdbc2.jdbc.SybDriver,com.sybase.jdbc2.jdbc.SybDriver@42e816]
registerDriver: driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@de6ced]
registerDriver: driver[className=com.mysql.jdbc.test.MyDriver,com.mysql.jdbc.test.MyDriver@1fb8ee3]//注册我自己写的驱动
java.sql.DriverManager.registerDriver(new MyDriver())
DriverManager.getConnection("jdbc:my_test_driver://localhost/quickstart") //我自己定义个格式
trying driver[className=com.sybase.jdbc2.jdbc.SybDriver,com.sybase.jdbc2.jdbc.SybDriver@42e816]
trying driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@de6ced]
trying driver[className=com.mysql.jdbc.test.MyDriver,com.mysql.jdbc.test.MyDriver@1fb8ee3]//因为注册驱动的时候,我放在第三个,所以第三次的时候成功了。
return MyDriver okgetConnection returning driver[className=com.mysql.jdbc.test.MyDriver,com.mysql.jdbc.test.MyDriver@1fb8ee3]
下面是一种常见的方式---

Class.forName和registerDriver的区别的更多相关文章
- 反射中Class.forName()和classLoader的区别
搞清楚两者之间区别前,我们来了解下类加载过程. 一.类加载过程 1.加载 通过一个类的全限定名来获取定义此类的二进制字节流. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构. 在内存中生 ...
- 在Java的反射中,Class.forName和ClassLoader的区别
前言 最近在面试过程中有被问到,在Java反射中Class.forName()加载类和使用ClassLoader加载类的区别.当时没有想出来后来自己研究了一下就写下来记录一下. 解释 在java中Cl ...
- Class.forName和ClassLoader.loadClass区别(转)
Java中class是如何加载到JVM中的:1.class加载到JVM中有三个步骤 装载:(loading)找到class对应的字节码文件. 连接:(linking)将对应的字节码文件读入 ...
- 反射中,Class.forName 和 classloader 的区别
https://blog.csdn.net/qq_27093465/article/details/52262340 java中class.forName()和classLoader都可用来对类进行加 ...
- 在 Java 的反射中,Class.forName 和 ClassLoader 的区别
1. 解释 在java中Class.forName()和ClassLoader都可以对类进行加载.ClassLoader就是遵循双亲委派模型最终调用启动类加载器的类加载器,实现的功能是“通过一个类的全 ...
- Java反射中Class.forName和classloader的区别
Java中Class.forName和classloader都可以用来对类进行加载. Class.forName除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块 ...
- Class.forName和ClassLoader的区别
一 看名字就知道了,一个是类的创建,一个类加载器 二 再看下Class.forName源码,调用了ClassLoader @CallerSensitive public static Class< ...
- class.forName 和 classLoader的区别
Java中的Class.forName()和ClassLoader都可以用来对类进行加载.Class.forName()除了将类的.class文件加载到JVM中 还会对类进行解释,执行类中的stati ...
- class.forName() 和 classLoader 的区别
相同点: java中class.forName() 和 classLoader 都可用来对类进行加载 不同店: 1.class.forName()除了将类的 .class ...
随机推荐
- 最小生成树-克鲁斯卡尔算法(kruskal's algorithm)实现
算法描述 克鲁斯卡尔算法是一种贪心算法,因为它每一步都挑选当前最轻的边而并不知道全局路径的情况. 算法最关键的一个步骤是要判断要加入mst的顶点是否会形成回路,我们可以利用并查集的技术来做. 并查集的 ...
- 设置Linux SSH登录后的欢迎信息
在这几个文件,各自都设置一下: /etc/motd /etc/issue 在/etc/ssh/sshd_config添加“Banner /etc/ssh/ssh_login_banner” 内容: \ ...
- druid数据源
Druid是一个JDBC组件,它包括三部分: DruidDriver 代理Driver,能够提供基于Filter-Chain模式的插件体系. DruidDataSource 高效可管理的数据库连接池 ...
- 如何构建Win32汇编的编程环境(ONEPROBLEM个人推荐)
如何构建Win32汇编的编程环境(ONEPROBLEM个人推荐)1.首先要下载我提供的软件包(里面已经包含所有所需软件); 2.把它解压到D盘根目录下(如果需要安装在其它的地方,请注意设好路径); ...
- bit byte哪些事
1.bit 电脑中最小的计量单位,比如0或1代表一个bit,简称“位” 2.byte 电脑存储的基本单位.因为上面的bit小弟太小了,所以产生了byte.由8个bit存成了byte,最小为0最大为11 ...
- UML状态图
状态图(Statechart digram)是系统分析的一种经常使用工具,系统分析员在对系统建模时,最先考虑的不是基于活动之间的控制流,而是基于状态之间的控制流,由于系统中对象的状态变化最易被发现和理 ...
- Go的安装和使用/卸载/升级、安装指定版本
mac: 1.brew install go默认安装最新的,更新go也是这条命令,建议这个方法,省事 2.从官网https://golang.org/dl/下载pkg包安装,官方说1.12是最后一个支 ...
- Objective-C:MRC手动释放对象内存举例(引用计数器)
手机内存下的类的设计练习: 设计Book类, 1.三个成员变量: title(书名)author(作者).price(价格) 2.不使用@property,自己完成存取方法(set方法,get方 ...
- 给定任意字符串,计算一共能组合成多少个单词bing
CSDN编程挑战里的题目 例如有一个字符串"iinbinbing",截取不同位置的字符‘b’.‘i’.‘n’.‘g’组合成单词"bing".若从1开始计数的话, ...
- 解决:HTTP 错误 404.2 - Not Found. 由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面
错误重现: 在发布网站的过程中,虽然不是第一次发布了,但是还是遇到了很多的问题.为了以后可以轻松解决此类问题还是积累下来比较好. 问题:HTTP 错误 404.2 - Not Found. 由于 We ...