java与SPI

现在大家连数据库估计已经很少用JDBC了,我也是最近发现在JDBC4.0以后(对应JDK7+),JDBC不用写Class.forName了。这时候就要扯进来一个技术——SPI(Service Provider Interface)。它是用来动态实现接口的。而在JDK中典型的用到该技术的,就是JDBC了。

现在JDBC获取连接如下:

Connection connection = DriverManager.getConnection("http://url", "username", "pwd");

跟进DriverManager.class,有一段static代码:

    static {
        loadInitialDrivers();
        println("JDBC DriverManager initialized");
    }

java.sql.DriverManager#loadInitialDrivers中,有下面一句话:

ServiceLoader loadedDrivers = ServiceLoader.load(Driver.class);

从这句话就会加载出N多的Driver,你所添加的都有。
本次测试使用的mysql的jar,mysql的原来的classForName是com.mysql.jdbc.Driver,跟进此类,发现在此类的jar下有一文件夹:META_INF/services,内有一文件java.sql.Driver。这个文件名正好是上面load方法中Driver的全路径名。

image.png

这个也是一个类,其唯一实现是com.mysql.jdbc.Driver类。

由此我们可以理出,SPI就是在根目录下,建一文件夹META_INF/services,你想动态加载什么接口将某接口的全路径名称定义为一文件名,内部每一行写一个实现类的全类名。然后在加载时会将该文件中所有的类都加载进去。


该功能旨在统一不同厂商的不同实现,A制定标准,其他采用A方案者进行实现他自己的内容,A只需要在指定地方加载某些实现的文件即可。

该功能在Spring 和dubbo 中,有注解@SPI,在spring boot中体现为自动装配

你可能感兴趣的:(java与SPI)