SPI机制

HeJin大约 1 分钟数据库技术JDBC

连接获取源码分析

关键代码在 DriverManager.getConnection()

@Test
public void test3() throws SQLException {
    // 1.定义要素
    String url = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8&&useSSL=false&serverTimezone=GMT%2B8";
    String username = "root";
    String password = "root";

    // 4.获取连接
    Connection connection = DriverManager.getConnection(url, username, password);

    System.out.println(connection);
}

查看源码(JDK8)

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");
}
image-20221202120825903
image-20221202120825903

当MySQL的驱动被SPI加载到jvm中之后,就会被注册到DriverManager。

image-20221202122349977
image-20221202122349977
public static synchronized void registerDriver(java.sql.Driver driver)
    throws SQLException {

    registerDriver(driver, null);
}
image-20221202123218789
image-20221202123218789

获取连接

image-20221202122518096
image-20221202122518096
image-20221202122759877
image-20221202122759877

简单使用SPI

JDK在项目启动的时候,会到META-INF/services/加载文件,文件名就是接口,内容是接口的实现类。SPI会通过工具类ServiceLoader反射把接口的实现类加载到JVM中。

Animal接口

public interface Animal {
}

Ca和Dog实现类

public class Cat implements Animal{
}
public class Dog implements Animal{
}

META-INF/services/com.sanfen.Animal

com.sanfen.Cat
com.sanfen.Dog

使用ServiceLoader加载实现类:

public class Client {
    public static void main(String[] args) {
        ServiceLoader<Animal> loadedDrivers = ServiceLoader.load(Animal.class);
        Iterator<Animal> driversIterator = loadedDrivers.iterator();
        while (driversIterator.hasNext()){
            Animal animal = driversIterator.next();
            System.out.println(animal);
        }
    }
}

结果:

com.sanfen.Cat@45ee12a7
com.sanfen.Dog@330bedb4

Process finished with exit code 0

我们并没有创建Cat和Dog对象,是ServiceLoader加载配置文件,通过反射创建的。我们只是传入了接口Animal.class。SPI(Service Provider Interface)会自己去对应位置加载解析文件。