dubbo SPI功能解析(一)

SPI配置说明

若是须要扩展Dubbo Protocol接口实现,须要在本身的扩展jar中新增文本文件 META-INF/dubbo/com.alibaba.dubbo.rpc.Protocol ,文件内容为java

xxx=com.alibaba.xxx.XxxProtocol
复制代码

实现类为bash

package com.alibaba.xxx;
 
import com.alibaba.dubbo.rpc.Protocol;
 
public class XxxProtocol implements Protocol { 
    // ...
}
复制代码

SPI的扩展配置都是经过配置标签属性来实现的app

<dubbo:protocol name="xxx" />
复制代码

SPI特性

SPI自动包装SPI Auto Wrapthis

package com.alibaba.xxx;
 
import com.alibaba.dubbo.rpc.Protocol;
 
public class XxxProtocolWrapper implements Protocol {
    Protocol impl;
 
    public XxxProtocolWrapper(Protocol protocol) { impl = protocol; }
 
    //after interface method is executed,the method in extension will be executed
    public void refer() {
        //... some operation
        impl.refer();
        // ... some operation
    }
 
    // ...
}
复制代码

SPI包装器实现类也实现了SPI接口,包装器类名必须以Wrapper结尾,构造器方法须要传入真正的SPI实现类,当经过ExtensionLoader SPI实现类加载器加载SPI实现类时,会自动返回具体实现类的包装实现,经过这种方式类型了相似Spring AOP的功能。包装器实现类能够有多个,这样能够实现链式结构。url

最典型的实现见ProtocolFilterWrapper将Protocol协议生成的Invoker实现包装了一层Filter过滤器链spa

SPI依赖注入(自动加载)

public interface CarMaker {
    Car makeCar();
}
 
public interface WheelMaker {
    Wheel makeWheel();
}
复制代码

假设有两个SPI接口CarMaker,WheelMaker如上 CarMaker implementation:代理

public class RaceCarMaker implements CarMaker {
    WheelMaker wheelMaker;
 
    public setWheelMaker(WheelMaker wheelMaker) {
        this.wheelMaker = wheelMaker;
    }
 
    public Car makeCar() {
        // ...
        Wheel wheel = wheelMaker.makeWheel();
        // ...
        return new RaceCar(wheel, ...);
    }
}
复制代码

当经过ExtensionLoader来加载CarMaker实现时,会自动加载WheelMaker的实现类设置到wheelMaker的属性中实现依赖注入的功能,若是WheelMaker有多个实现类,会建立WheelMaker自适应实现做为实现类。若是只有一个实现类既为该实现类。code

SPI自适应实现

public interface CarMaker {
    Car makeCar(URL url);
}
 
public interface WheelMaker {
    Wheel makeWheel(URL url);
}

public class RaceCarMaker implements CarMaker {
    WheelMaker wheelMaker;
 
    public setWheelMaker(WheelMaker wheelMaker) {
        this.wheelMaker = wheelMaker;
    }
 
    public Car makeCar(URL url) {
        // ...
        Wheel wheel = wheelMaker.makeWheel(url);
        // ...
        return new RaceCar(wheel, ...);
    }
}
复制代码

能够看到SPI接口实现类方法都增长了URL参数,最关键的Wheel wheel = wheelMaker.makeWheel(url); wheelMaker自适应类实现了一个薄薄的代理层,会根据Url对象中预约义的key,默认使用SPI的类名简称 url.get("wheelMaker")获取真正的实现名称,而后经过ExtensionLoader获取真实实现名对应的实现类。 dubbo将XML配置中全部的信息都封装在URL中,自适应实现类经过修改XML配置切换具体实现类的。对象

相关文章
相关标签/搜索