首页 > 数据库 >关于MySQL的JDBC Driver加载过程详解

关于MySQL的JDBC Driver加载过程详解

时间:2023-05-26 11:24:24浏览次数:38  
标签:DriverManager jdbc drivers Driver JDBC MySQL println 加载

在使用JDBC时,都需要提前加载对应数据库的Driver类,MySQL为例:

Class.forName("com.mysql.jdbc.Driver")

但是不写这句代码也可以让 com.mysql.jdbc.Driver 类成功加载,这就涉及到 java.sql.DriverManager 类了,先看一下代码:

public class DriverManager {
// 注册驱动的集合
private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers
= new CopyOnWriteArrayList<>();
// 初始化驱动
static {
loadInitialDrivers();
println("JDBC DriverManager initialized");
}

它位于启动类路径之下,由 BootStrap ClassLoader 加载,在加载的初始化过程中,运行 static 代码块里的 loadInitialDrivers() 方法,在该方法里加载了 Driver 类,具体如下:

private static void loadInitialDrivers() {
String drivers;
try {
drivers = AccessController.doPrivileged(new PrivilegedAction<String>
() {
public String run() {
return System.getProperty("jdbc.drivers");
}
});
} catch (Exception ex) {
drivers = null;
}
// 1)使用 ServiceLoader 机制加载驱动,即 SPI
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
ServiceLoader<Driver> loadedDrivers =
ServiceLoader.load(Driver.class);
Iterator<Driver> driversIterator = loadedDrivers.iterator();
try{
while(driversIterator.hasNext()) {
driversIterator.next();
}
} catch(Throwable t) {
// Do nothing
}
return null;
}
});
println("DriverManager.initialize: jdbc.drivers = " + drivers);
// 2)使用 jdbc.drivers 定义的驱动名加载驱动
if (drivers == null || drivers.equals("")) {
return;
}
String[] driversList = drivers.split(":");
println("number of Drivers:" + driversList.length);
for (String aDriver : driversList) {
try {
println("DriverManager.Initialize: loading " + aDriver);
// 这里的 ClassLoader.getSystemClassLoader() 就是 Application ClassLoader 类加载器
Class.forName(aDriver, true,
ClassLoader.getSystemClassLoader());
} catch (Exception ex) {
println("DriverManager.Initialize: load failed: " + ex);
}
}
}

可以看到,一开始定义了 drivers 属性,通过 System.getPorperty 方法试图获取系统变量中定义的 jdbc.drivers 变量值并赋给 drivers,如果结果不为空,再看标号 2)部分的代码,这段代码是使用 Application ClassLoader 加载 drivers 属性中指定的类。而系统变量中如果没有定义 jdbc.drivers,也不用担心,看标号 1)的代码部分,它使用 SPI 机制加载驱动类,如图:

mysql-connector-java-5.1.47.jar 中,含有 META-INF→services→java.sql.Driver 文件。在 SPI 机制中,只要对应文件夹下的文件名和类接口名对应,就可以通过 ServiceLoader.load() 方法加载对应文件中记录的实现了该接口的类(当然,具体过程比较复杂,有耐心的读者可以自行查看load函数的调用链)。

到此,就实现了不显示写出 Class.forName("com.mysql.jdbc.Driver"),也可以加载Driver类的功能。

 

标签:DriverManager,jdbc,drivers,Driver,JDBC,MySQL,println,加载
From: https://www.cnblogs.com/rockdow/p/17434235.html

相关文章

  • 5分钟搞定Linux安装Mysql5.7(简单快捷,建议收藏)
    本文记录下我近期在Linux环境下安装Mysql5.7的实践经历。服务器版本Mysql版本Centos7.65.7.321.下载Mysql下载地址:https://downloads.mysql.com/archives/community/进入页面后选择你需要的版本进行下载,这里提供了2种格式:tar.gz和tar。如果下载不方便,可以直接从我的网盘里面下......
  • MySQL常用命令
    #安装mysql后查看初始密码cat/var/log/mysqld.log#登录mysqlmysql-u[user]-p[密码]-h[远程主机ip]#本地登录可以简写为mysql-uroot-p#设置密码长度#【8.0】setglobalvalidate_password.length=6;#【5.7】setglobalvalidate_password_length=6;#设置......
  • 使用resource读取properties文件,出现Cause: java.sql.SQLException: No suitable driv
    ###Errorqueryingdatabase.Cause:java.sql.SQLException:Nosuitabledriverfoundforhttp://maven.apache.org###Theerrormayexistincom/louis/dao/UserMapper.xml###Theerrormayinvolvecom.louis.dao.UserMapper.getUserList###Theerroroccurred......
  • MySQL安装
    1、检查是否已经安装了mysql和mariadbrpm-qa|grepmysqlrpm-qa|grepmariadb#如果已经安装,就先卸载:rpm-e--nodeps软件名2、安装mysql按顺序安装:8.0.28-1.el7版本rpm-ivhmysql-community-common-8.0.28-1.el7.aarch64.rpmrpm-ivhmysql-community-cli......
  • MySQL-DQL
    准备测试表,先跟着执行下面的SQL#1.登录MySQL后#2.创建test_database数据库,不存在则创建createdatabaseifnotexiststest_database;#2.1.如果test_database库存在,可以根据自己意愿删除或换个名称dropdatabasetest_database;#删除test_database数据库#3.进入刚创建的库......
  • Mysql数据库遇到的问题及解决办法
    1、1205-Lockwaittimeoutexceeded;tryrestartingtransaction该异常代表数据库中有进程锁住了,会导致后续对数据库的操作都无法执行,需要杀掉锁住的进程 解决办法:1)、SELECT*FROMinformation_schema.INNODB_TRX;执行后找到名为trx_mysql_thread_id的列。2)、杀掉列中的......
  • MySQL学习进阶篇Day1
    1.存储引擎1.1MySQL体系结构  1).连接层最上层是一些客户端和链接服务,包含本地sock通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念,为通过认证安全接入的客户端提......
  • mysql之ddl之trancate
    截断,trancatetabletk_student即保留表结构,重新建表tk_student相比于delete这种dml,对数据操作(一条一条删除数据)的语句,效率要高很多。但delete也有优点,即可以回滚事务(反悔),而trancate(隐式提交)不能回滚(反悔)两种方法删除数据后,如果在添加语句,对于自增的变量(一般是主键),则delete......
  • MySQL基础
    1MySQL简介视频链接:黑马程序员MySQL数据库MySQL是一种开源的关系型数据库管理系统(RDBMS),由瑞典的MySQLAB公司开发。MySQL是目前最流行的关系型数据库之一,广泛应用于Web应用程序、企业级应用和大数据处理等领域。MySQL支持多用户同时访问同一个数据库实例,并提供了可扩展性......
  • MySQL存储引擎精简版
    存储引擎简介概念:其是存储数据,建立索引,更新查询数据等操作的技术支持,引擎是基于表的,所以又称表结构常见分类InnoDBMySQL5.5之后默认引擎特点:1.操作遵循ACID原则,支持事务2.支持行锁3,支持外键约束MyISAMMySQL早期默认引擎特点:1.不支持事务和外键约束,支持表锁......