Dubbo是由阿里巴巴开源的一款高性能、轻量级的开源Java Rpc(远程过程调用)框架,提供三大核心能力:面向接口的远程方法调用、智能容错和负载均衡、服务自动注册与发现。
在Dubbo的源码中,下面这种句式出现比较多,比如如下句式:通过ExtensionLoader获取Protocol接口的代理类。
Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
仔细翻看dubbo中的源码,Protocol接口的实现类有很多种,那么在程序的执行中怎么得到对应的实现类,怎么去动态的扩展接口实现,这些问题就是今天讨论的重点。
Spi全称为(Service Provider Interface),是Jdk内置的一种服务提供发现机制,目前有不少框架用他来做服务的拓展发现,简单说Spi是一种动态替换发现机制,使用Spi机制的优势是实现解耦,使第三方服务模块的装配控制逻辑与调用者的业务代码分离。
二、Java中JDK的Spi实现。
Java中如果想要使用SPI功能,先提供标准服务接口,然后在提供相关接口实现的调用者,这样就可以通过spi机制中约定好的信息进行查询相应的接口实现
SPI遵循以下约定
1)当服务提供者提供了一个服务(接口)的具体实现后,在classpath下的META-INF/services目录下创建一个以“接口全限定名”命名的文件,内容为实现类的全限定名。
2)接口实现类所在的jar包放在驻车鞥徐的classpath中;
3)主程序通过java.util.ServiceLoader动态状态实现模块(类),它通过扫描META-INF/services目录下的配置文件找到实现类的全限定名,把类加载到JVM。
4)Spi的实现类必须携带一个无参构造
JDK中的Spi机制应用比较广泛比如说common-logging、JDBC等,这里使用JDBC进行举例
1、JDBC接口定义
首先在java 中定义接口java.sql.Dirver并没有具体的实现,具体的实现由不同的厂商来提供
2、mysql实现
在mysql的jar包mysql-connector-java-6.0.6.jar中,可以找到META-INF/services目录,该目录下会有一个名字为java.sql.Driver的文件,文件内容是com.mysql.cj.jdbc.Driver,这里面的内容就是针对Java中定义的接口的实现。
3、查找调用在DriverManager类的静态代码块loadInitialDrivers();方法中
感兴趣的小伙伴可以去翻看源码哈~这里我就不展示源码了,做一个简单的模拟案例进行展示,项目目录如下所示
源码如下:
Driver类
package city.albert; /** * @author niunafei * @function * @email niunafei0315@163.com * @date 2020/8/25 5:09 PM */ public interface Driver { /** * 模拟获取驱动名称 * @return */ String driverName(); }