zoukankan      html  css  js  c++  java
  • 设计模式

    参考

    清幽之地 https://www.jianshu.com/p/3a3edbcd8f24

    一、什么是SPI

    SPI ,全称为 Service Provider Interface,是一种服务发现机制。它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。

    这一机制为很多框架扩展提供了可能,比如在Dubbo、JDBC中都使用到了SPI机制。我们先通过一个很简单的例子来看下它是怎么用的。



    二、jdk的SPI

    代码

    首先,我们需要定义一个接口,SPIService

    package com.viewscenes.netsupervisor.spi;
    public interface SPIService {
        void execute();
    }
    

    然后,定义两个实现类,没别的意思,只输入一句话。

    package com.viewscenes.netsupervisor.spi;
    public class SpiImpl1 implements SPIService{
        public void execute() {
            System.out.println("SpiImpl1.execute()");
        }
    }
    ----------------------我是乖巧的分割线----------------------
    package com.viewscenes.netsupervisor.spi;
    public class SpiImpl2 implements SPIService{
        public void execute() {
            System.out.println("SpiImpl2.execute()");
        }
    }
    

    最后呢,要在ClassPath路径下配置添加一个文件。文件名字是接口的全限定类名,内容是实现类的全限定类名,多个实现类用换行符分隔。
    文件路径如下:


     
    SPI配置文件位置

    内容就是实现类的全限定类名:

    com.viewscenes.netsupervisor.spi.SpiImpl1
    com.viewscenes.netsupervisor.spi.SpiImpl2
    

    测试

    然后我们就可以通过ServiceLoader.load或者Service.providers方法拿到实现类的实例。其中,Service.providers包位于sun.misc.Service,而ServiceLoader.load包位于java.util.ServiceLoader

    public class Test {
        public static void main(String[] args) {    
            Iterator<SPIService> providers = Service.providers(SPIService.class);
            ServiceLoader<SPIService> load = ServiceLoader.load(SPIService.class);
    
            while(providers.hasNext()) {
                SPIService ser = providers.next();
                ser.execute();
            }
            System.out.println("--------------------------------");
            Iterator<SPIService> iterator = load.iterator();
            while(iterator.hasNext()) {
                SPIService ser = iterator.next();
                ser.execute();
            }
        }
    }
    

    两种方式的输出结果是一致的:

    SpiImpl1.execute()
    SpiImpl2.execute()
    --------------------------------
    SpiImpl1.execute()
    SpiImpl2.execute()


    优缺点

    优点:将业务代码和具体实现类解耦,方便扩展。如需增加新逻辑,无需修改主流程,直接在PI配置文件增加实现类的全限定名即可。

    缺点:颗粒度不够细,无法准确定位某一个实现类。要执行就执行所有的实现类。

    三、Dubbo 的 SPI(对jdk SPI的颗粒度改进)

    Dubbo的配置文件

    cluster这里可以准确制定一个实现类

    SPI配置文件

    和jdk只包含实现类的全限定名不同,这里是key value 模式

     
     
  • 相关阅读:
    微软官方原版Windows Server 2003 R2下载
    [转]Windows Server 2003/2008 官方VHD转换为VMWARE的VMDK
    [转]Windows Server 2003/2008 原版ISO下载地址
    [转]免重启修改Windows远程桌面3389端口脚本
    [转]VMware 虚拟机硬盘镜像共享(98、ME、2000、2003)
    鹦鹉的性格
    [转]关于工作与生活的转帖
    GB2312 字符串,单字节英文,双字节中文的完整类实现
    越狱第2季14集已经出来了!!
    测试一下Windows live Writer,顺便怀念一下单位以前的几个猫咪。
  • 原文地址:https://www.cnblogs.com/frankcui/p/13407458.html
Copyright © 2011-2022 走看看