zoukankan      html  css  js  c++  java
  • dubbo之SPI解析

    摘自 https://blog.csdn.net/qiangcai/article/details/77750541

    二  什么是SPI技术

             感觉自己的语言描述不是很精准,就不再自己创造了,在网上拷贝了一段描述,讲明了什么是SPI技术,为什么要用SPI,用SPI有什么好处。内如下:  SPI的全名为Service Provider Interface.大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的。在java.util.ServiceLoader的文档里有比较详细的介绍。简单的总结下java spi机制的思想。我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。 java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,java spi的具体约定为:当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。 基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。jdk提供服务实现查找的一个工具类:java.util.ServiceLoader

    三  JDK中的SPI技术

        JDK中拥有SPI的支持,主要涉及java.util.ServiceLoader类的使用,我写了一个小的DEMO让我们初步理解下SPI的使用。首先我写了一个接口代码如下:

    package spi;
    
    /**
    * Created by Administrator on 2017/8/28.
    */
    public interface DubboService {
    
    public void sayHello();
    }

    然后写了这个接口的两个实现类

    package spi;
    
    /**
    * Created by Administrator on 2017/8/28.
    */
    public class RedService implements DubboService {
    public void sayHello() {
    
    System.out.println("我是RedService服务实现");
    
    }
    }
    package spi;
    
    /**
    * Created by Administrator on 2017/8/28.
    */
    public class YellowService implements DubboService {
    public void sayHello() {
    System.out.println("我是YellowService服务实现");
    
    }
    }

    然后写了一个main函数类

    package spi;
    import java.util.Iterator;
    import java.util.ServiceLoader;
    
    /**
    * Created by Administrator on 2017/8/28.
    */
    public class ServiceMain {
    
    public static void main(String[] args){
    
    ServiceLoader<DubboService> spiLoader = ServiceLoader.load(DubboService.class);
    Iterator<DubboService> iteratorSpi=spiLoader.iterator();
    while (iteratorSpi.hasNext()){
    DubboService dubboService=iteratorSpi.next();
    dubboService.sayHello();
    }
    
    }
    }

    然后在META-INF文件夹下创建了services文件夹,并在services文件夹下创建了一个文件,文件名以接口的全限定名来命名,我这里是spi.DubboService。然后在这个文件中填入这个接口的两个实现类,类中间以换行隔开。到这里所有准备工作已经完成,开始执行ServiceMain的主函数吧! 执行以后输出了日志打印
    1.我是RedService服务实现
    2.我是YellowService服务实现
    分析main函数中的代码,ServiceLoader类是JDK自带的哦!调用load方法即可加载接口参数的所有实现!看到这里是不是在想在META-INF文件夹下创建services/接口全限定名是不是固定写法!好吧,我们跟进到ServiceLoader类中。第一行代码就是private static final String PREFIX = "META-INF/services/"; 是不是立马就明白了ServiceLoader类中已经将配置路径固定好了(如果感兴趣也可以自己写个类来实现ServiceLoader的功能),调用load方法,根据传入的接口参数找到该接口的对应文件,然后一行一行的读取文件中的实现类,使用java反射机制实例化接口的实现对象。到这里SPI技术的原理应该理解了。也可以看看ServiceLoader类的源码能更深入的理解!看看我的目录接口如下图:

    新建的spi.DubboService中的内容如下: 

     dubbo 源码解析参考

    https://blog.csdn.net/u012117723/article/details/80734653

    https://blog.csdn.net/u012117723/article/details/80742790

  • 相关阅读:
    pku2351 Colored Sticks
    JSOI2010 满汉全席
    享元模式
    适配器模式
    合成模式
    原型模式
    创建型设计模式
    建造者模式
    装饰模式
    单例模式
  • 原文地址:https://www.cnblogs.com/wangzhanhua/p/10376357.html
Copyright © 2011-2022 走看看