使用Class.forName加载驱动
使用JDBC连接数据库的时候,需要先加载驱动。可以通过Class.forName声明要加载的驱动,加载这个词在这里其实不太明确,因为Class.forName不只是把类加载到了内存中,还会初始化(static块中的代码会被执行)。注册驱动其实就发生在 static 块中。比如mysql的驱动com.mysql.cj.jdbc.Driver
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
所以这里是无法使用ClassLoader.loadClass()
来替换的。
不使用Class.forName
在JDBC 4.0之后,可以通过SPI的方式加载驱动。
在驱动相应的jar包里,META-INF/services目录下,会有名为java.sql.Driver的文件,里面的内容是驱动的全路径名。
比如在mysql-connector-java-8.0.16.jar
中,META-INF/services目录下的java.sql.Driver内容为:
com.mysql.cj.jdbc.Driver
DriverManager初始化的时候会通过SPI加载所有Driver接口的实现类
在DriverManager中有如下代码
static {
loadInitialDrivers();
println("JDBC DriverManager initialized");
}
loadInitialDrivers
方法中包含了两部分
- 通过系统属性jdbc.drivers加载驱动
- 通过SPI的方式加载
看一下通过SPI方式加载的部分
AccessController.doPrivileged</