本文已参与「新人创作礼」活动,一起开启掘金创作之路。
先看一个案例
提问:为什么要先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 下服务提供者接口实现。