数据库驱动为什么要先Class.forName

266 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

先看一个案例

在这里插入图片描述

提问:为什么要先Class.forName?

答:在JDBC规范中明确要求这个Driver类必须向DriverManager注册自己。

下面是h2的driver类的实现: 在这里插入图片描述 在这里插入图片描述

作用

方便DriverManager跟踪所有可用的JDBC驱动,并在用户需要时(openConnection)选择合适的驱动提供给用户。 在这里插入图片描述

避免了开发者直接new。

写"com.mysql.jdbc.Driver d = new com.mysql.jdbc.Driver();"

仅仅为了初始化一个类而new一个类实例没有必要。

直接使用Class.forName(String name)初始化就可以。DriverManager类的getConnection()方法的存在本身就是帮助用户调用Driver里面的各种方法连接数据库,JDK都做好了,开发者就没必要自己写这些机械化的重复工作。

提问:为什么去掉Class.forName("org.h2.Driver")也能运行?

在这里插入图片描述 答:JDBC4之前没用SPI,也没用static注册到驱动管理器,所以看到有Class.forName("org.h2.Driver")。而现在大多JDK8项目,通过SPI注册自然就不需要Class.forName("org.h2.Driver")。

通过SPI机制查找并注册的驱动: 在这里插入图片描述

SPI

SPI 服务提供者接口(Service Provider Interface)。

优点:我们只需要面向接口编程,而不用直接操作实现类。插件化,通过在 Classpath 下引入含有指定接口实现的 jar 包,我们就能完成向应用程序安装插件。

使用方法:通过 ServiceLoader 来加载位于 Classpath 下服务提供者接口实现。