• 设计模式


    参考

    清幽之地 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 模式

     
     
  • 相关阅读:
    【类库】容器对象(List、DataTable、 DataView、Dictionary)
    一些基础知识(一)
    编程模式之15---行为型----命令模式
    .NET学习之路----我对P/Invoke技术的理解(一)
    编程模式之十四----行为型----职责链模式
    web service 学习
    在Windows Server 2008中布置Web站点时遇到的问题及解决办法
    运算符的优先级和结合 性
    打包工具进行打包文件时要注意要点
    登录测试点
  • 原文地址:https://www.cnblogs.com/frankcui/p/13407458.html
Copyright © 2020-2023  润新知