SPI在数据库驱动中的应用
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.3.3</version>
</dependency>
package org.example;
import java.sql.Driver;
import java.sql.DriverManager;
public class App
{
private final static Logger logger = LoggerFactory.getLogger(App.class);
public static void main( String[] args ) throws IOException, ClassNotFoundException {
Class.forName("java.sql.DriverManager");
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
logger.info("{}", driver.getClass().getName());
}
}
}
Java提供的驱动管理器,DriverManager
package java.sql;
public class DriverManager {
// List of registered JDBC drivers
private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();
private DriverManager(){}
/**
* Load the initial JDBC drivers by checking the System property
* jdbc.properties and then use the {@code ServiceLoader} mechanism
*/
static {
loadInitialDrivers();
println("JDBC DriverManager initialized");
}
private static void loadInitialDrivers() {
String drivers;
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;
}
});
}
public static synchronized void registerDriver(java.sql.Driver driver)
throws SQLException {
registerDriver(driver, null);
}
public static synchronized void registerDriver(java.sql.Driver driver,
DriverAction da)
throws SQLException {
/* Register the driver if it has not already been added to our list */
if(driver != null) {
registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
} else {
throw new NullPointerException();
}
println("registerDriver: " + driver);
}
}
DriverManager类加载的时候执行loadInitialDrivers()通过ServiceLoader.load(Driver.class)获取所有第三方库实现的Driver;虽然只是遍历一遍所有的Driver实例但是类加载器会加载这些类到jvm届时将执行Driver实现类的静态代码块把自己注册到DriverManager即添加到DriverManager的registeredDrivers容器中。
mysql实现的Driver
package com.mysql.cj.jdbc;
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
//
// Register ourselves with the DriverManager
//
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
/**
* Construct a new driver and register it with DriverManager
*/
public Driver() throws SQLException {
// Required for Class.forName().newInstance()
}
}
postgresql实现的Driver
package org.postgresql;
public class Driver implements java.sql.Driver {
private static @Nullable Driver registeredDriver;
static {
try {
register();
} catch (SQLException var1) {
throw new ExceptionInInitializerError(var1);
}
}
public static void register() throws SQLException {
if (isRegistered()) {
throw new IllegalStateException("Driver is already registered. It can only be registered once.");
} else {
Driver registeredDriver = new Driver();
DriverManager.registerDriver(registeredDriver);
Driver.registeredDriver = registeredDriver;
}
}
}