面试官:JDBC 是如何打破双亲委派模型的?

开发 前端
在 Java 中,JDBC(Java Database Connectivity)是用于与数据库进行交互的标准 API。JDBC 并不是直接打破双亲委派模型,而是通过 SPI 机制加上线程上下文类加载器(Thread.currentThread().getContextClassLoader())的方式,绕过了传统的类加载委托机制。

在 Java 中,JDBC(Java Database Connectivity)是用于与数据库进行交互的标准 API。JDBC 并不是直接打破双亲委派模型,而是通过 SPI 机制加上线程上下文类加载器(Thread.currentThread().getContextClassLoader())的方式,绕过了传统的类加载委托机制。这种设计既保留了双亲委派模型的核心优势,又实现了对第三方 JDBC 驱动程序的动态加载。

1. JDBC 打破双亲委派模型的缘由

在 Java 中,DriverManager 是 JDBC 的核心类,用于管理 JDBC 驱动程序并建立数据库连接。但是DriverManager 所在的类加载器(扩展类加载器或启动类加载器)通常无法直接加载第三方 JDBC 驱动程序(例如 MySQL 的 com.mysql.cj.jdbc.Driver),因为这些驱动程序是由应用程序类加载器加载的。

为了能够加载第三方 JDBC 驱动程序,JDBC 会使用线程上下文类加载器(Thread.currentThread().getContextClassLoader())来加载驱动程序。线程上下文类加载器是一个特殊机制,它允许线程在其上下文中切换类加载器。通过这种方式,JDBC 可以绕过传统的双亲委派模型,使用特定的类加载器(通常是应用程序类加载器)来加载 JDBC 驱动程序。

2. 线程上下文类加载器+SPI 机制

  • Java 提供了 SPI 机制来发现和加载服务实现。对于 JDBC,各个数据库厂商实现 java.sql.Driver 接口,并将实现类的全限定名配置在 META - INF/services/java.sql.Driver 文件中。下面是MySQL驱动中的SPI配置和Oracle驱动中的SPI配置

image.pngimage.png

image.pngimage.png

  • 当应用程序需要使用 JDBC 驱动时,核心类库中的 DriverManager 类负责加载驱动。DriverManager 使用线程上下文类加载器( Thread.currentThread().getContextClassLoader() )来加载 JDBC 驱动实现类。
  • 线程上下文类加载器通常是应用程序类加载器( AppClassLoader ),它可以加载应用程序的类路径下的类,包括各个数据库厂商提供的 JDBC 驱动实现类。这就打破了双亲委派模型中类加载器自下而上委派的规则,因为它不是从启动类加载器开始查找驱动类,而是从应用程序类加载器开始查找,使得数据库厂商的 JDBC 驱动类能够被正确加载。

通过这种方式,JDBC 打破了双亲委派模型,允许第三方 JDBC 驱动程序由应用程序类加载器加载,而 DriverManager 仍然由扩展类加载器加载。

责任编辑:武晓燕 来源: 玄武后端技术栈
相关推荐

2023-02-03 07:24:49

双亲委派模型

2021-01-06 09:51:19

类加载器双亲委派模型

2023-08-04 08:53:42

2023-12-06 12:11:43

类加载器双亲委派模型

2024-02-22 15:36:23

Java内存模型线程

2023-10-30 01:02:56

Java类类加载器双亲委派

2024-02-04 10:08:34

2024-12-25 15:44:15

2015-08-13 10:29:12

面试面试官

2021-03-01 08:54:39

开发双亲委派

2021-04-19 18:56:58

大数字符串运算

2024-05-11 15:11:44

系统软件部署

2023-02-08 07:04:20

死锁面试官单元

2024-10-15 10:00:06

2021-09-07 10:44:33

Java 注解开发

2010-08-12 16:28:35

面试官

2021-01-18 05:13:04

TomcatHttp

2025-02-26 12:19:52

2025-03-10 11:48:22

项目服务设计

2021-09-27 07:11:18

MySQLACID特性
点赞
收藏

51CTO技术栈公众号