• 分布式的几件小事(五)dubbo的spi思想是什么


    1.什么是SPI机制

    SPI 全称为 Service Provider Interface,是一种服务发现机制。
    SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。
    正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。SPI 机制在第三方框架中也有所应用,比如jdbc。

    java定义了一套jdbc的接口,但是java是没有提供jdbc的实现类。
    但是实际上项目跑的时候,要使用jdbc接口的哪些实现类呢?一般来说,我们要根据自己使用的数据库,比如msyql,你就将mysql-jdbc-connector.jar,引入进来;oracle,你就将oracle-jdbc-connector.jar,引入进来。
    在系统运行的时候,碰到你使用jdbc的接口,他会在底层使用你引入的那个jar中提供的实现类。

    2.dubbo的SPI机制

    Dubbo 并未使用 Java 原生的 SPI 机制,而是对其进行了增强,使其能够更好的满足需求。在 Dubbo 中,SPI 是一个非常重要的模块。基于 SPI,我们可以很容易的对 Dubbo 进行拓展。

    dubbo的设计原则
    采用 Microkernel + Plugin 模式,Microkernel 只负责组装 Plugin,Dubbo 自身的功能也是通过扩展点实现的,也就是 Dubbo 的所有功能点都可被用户自定义扩展所替换。

    3.dubbo spi使用

    Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();

    Protocol接口,dubbo要判断一下,在系统运行的时候,应该选用这个Protocol接口的哪个实现类来实例化对象来使用呢?

    他会去找一个你配置的Protocol,他就会将你配置的Protocol实现类,加载到jvm中来,然后实例化对象,就用你的那个Protocol实现类就可以了

    微内核,可插拔,大量的组件,Protocol负责rpc调用的东西,你可以实现自己的rpc调用组件,实现Protocol接口,给自己的一个实现类即可。

    这行代码就是dubbo里大量使用的,就是对很多组件,都是保留一个接口和多个实现,然后在系统运行的时候动态根据配置去找到对应的实现类。如果你没配置,那就走默认的实现好了,没问题。

    @SPI("dubbo")  
    public interface Protocol {  
          
        int getDefaultPort();  
      
        @Adaptive  
        <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;  
      
        @Adaptive  
        <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;  
    
        void destroy();  
      
    }  
    

    在dubbo自己的jar里,在/META_INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol文件中:

    dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol
    http=com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
    hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol
    

    image.png

    所以说,这就看到了dubbo的spi机制默认是怎么使用的了,其实就是Protocol接口,@SPI(“dubbo”)说的是,通过SPI机制来提供实现类,实现类是通过dubbo作为默认key去配置文件里找到的,配置文件名称与接口全限定名一样的,通过dubbo作为key可以找到默认的实现了就是com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol。

    dubbo的默认网络通信协议,就是dubbo协议,用的DubboProtocol

    如果想要动态替换掉默认的实现类,需要使用@Adaptive接口,Protocol接口中,有两个方法加了@Adaptive注解,就是说那俩接口会被代理实现。

    什么意思呢?

    比如这个Protocol接口搞了俩@Adaptive注解标注了方法,在运行的时候会针对Protocol生成代理类,这个代理类的那俩方法里面会有代理代码,代理代码会在运行的时候动态根据url中的protocol来获取那个key,默认是dubbo,你也可以自己指定,你如果指定了别的key,那么就会获取别的实现类的实例了。

    通过这个url中的参数不通,就可以控制动态使用不同的组件实现类

    4.怎么来自己扩展dubbo中的组件

    自己写个工程,要是那种可以打成jar包的,里面的src/main/resources目录下,搞一个META-INF/services,里面放个文件叫:com.alibaba.dubbo.rpc.Protocol,文件里搞一个my=com.zhss.MyProtocol。自己把jar弄到nexus私服里去。

    然后自己搞一个dubbo provider工程,在这个工程里面依赖你自己搞的那个jar,然后在spring配置文件里给个配置:

    <dubbo:protocol name=”my” port=”20000” />
    

    这个时候provider启动的时候,就会加载到我们jar包里的my=com.zhss.MyProtocol这行配置里,接着会根据你的配置使用你定义好的MyProtocol了,这个就是简单说明一下,你通过上述方式,可以替换掉大量的dubbo内部的组件,就是扔个你自己的jar包,然后配置一下即可。

    dubbo里面提供了大量的类似上面的扩展点,就是说,你如果要扩展一个东西,只要自己写个jar,让你的consumer或者是provider工程,依赖你的那个jar,在你的jar里指定目录下配置好接口名称对应的文件,里面通过key=实现类。

    然后对对应的组件,用类似dubbo:protocol用你的哪个key对应的实现类来实现某个接口,你可以自己去扩展dubbo的各种功能,提供你自己的实现。

  • 相关阅读:
    scrum立会报告+燃尽图(第三周第一次)
    scrum立会报告+燃尽图(第二周第七次)
    scrum立会报告+燃尽图(第二周第六次)
    scrum立会报告+燃尽图(第二周第五次)
    scrum立会报告+燃尽图(第二周第四次)
    006_for
    005_while
    003_if_else
    002_how to use getpass
    图像旋转
  • 原文地址:https://www.cnblogs.com/jack1995/p/10921146.html
Copyright © 2020-2023  润新知