甜腻的嘴角|Dubbo如何通过SPI提高框架的可扩展性?


甜腻的嘴角|Dubbo如何通过SPI提高框架的可扩展性?介绍最近看了一下Dubbo的源码 , 国人写的框架和国外的果然是两种不同的风格 , Dubbo的源码还是比较清晰容易懂的 。 Spring框架一个Bean的初始化过程就能绕死在源码中.
Dubbo的架构是基于分层来设计的 , 每层执行固定的功能 , 上层依赖下层 , 下层的改变对上层不可见 , 每层都是可以被替换的组件
甜腻的嘴角|Dubbo如何通过SPI提高框架的可扩展性?Service和Config为API接口层 , 让Dubbo使用者方便的发布和引用服务其他各层均为SPI层 , 意味着每层都是组件化的 , 可以被替换
例如 , 注册中心可以用Redis , Zookeeper 。 传输协议可以用dubbo , rmi , hessian等 。 网络通信可以用mina , netty 。 序列化可以用fastjson , hessian2 , java原生的方式等
SPI 全称为 Service Provider Interface , 是一种服务发现机制 。 SPI 的本质是将接口实现类的全限定名配置在文件中 , 并由服务加载器读取配置文件 , 加载实现类 。 这样可以在运行时 , 动态为接口替换实现类 。 正因此特性 , 我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能
那么Dubbo的SPI是怎么实现的呢?先来了解一下Java SPI
Java SPIJava SPI是通过策略模式实现的 , 一个接口提供多个实现类 , 而使用哪个实现类不在程序中确定 , 而是配置文件配置的 , 具体步骤如下

  1. 定义接口及其对应的实现类
  2. 在META-INF/services目录下创建以接口全路径命名的文件
  3. 文件内容为实现类的全路径名
  4. 在代码中通过java.util.ServiceLoader#load加载具体的实现类
写个Demo演示一下
甜腻的嘴角|Dubbo如何通过SPI提高框架的可扩展性?public interface Car {void getBrand();}public class benzCar implements Car {@Overridepublic void getBrand() {System.out.println("benz");}}public class BMWCar implements Car {@Overridepublic void getBrand() {System.out.println("bmw");}}org.apache.dubbo.Car的内容如下
org.apache.dubbo.BenzCarorg.apache.dubbo.BMWCar测试类
public class JavaSpiDemo {public static void main(String[] args) {ServiceLoader carServiceLoader = ServiceLoader.load(Car.class);// benz// bmwcarServiceLoader.forEach(Car::getBrand);}}Dubbo SPI
甜腻的嘴角|Dubbo如何通过SPI提高框架的可扩展性?用Dubbo SPI将上面的例子改造一下
@SPIpublic interface Car {void getBrand();}public class BenzCar implements Car {@Overridepublic void getBrand() {System.out.println("benz");}}public class BMWCar implements Car {@Overridepublic void getBrand() {System.out.println("bmw");}}org.apache.dubbo.quickstart.Car的内容如下
benz=org.apache.dubbo.quickstart.BenzCarbmw=org.apache.dubbo.quickstart.BMWCar测试类
public class DubboSpiDemo {public static void main(String[] args) {ExtensionLoader


推荐阅读