学习源码之SPI机制

目录

一、什么是SPI

二、SPI的作用

三、如何使用

四、流程图

五、源码学习

1、ServiceLoader.load(Class class)

2、serviceLoader.iterator()

3、iterator.hasNext()

4、iterator.next()

六、拓展


一、什么是SPI

SPI是Java提供的服务发现接口,它的全称是Service-Provide-Interface,由用户提供一个抽象接口,实现的子类可以动态扩展,而不需要改动到之前的逻辑,有点像策略模式。

SPI实现接口编程+策略模式+配置文件的动态加载机制。

二、SPI的作用

在模块化设计中,模块之间实现接口编程,将装配的控制权放在程序之外,模块间彻底解藕

三、如何使用

首先创建一个接口和多个实现类,在main文件夹下创建resource文件夹,resource和java文件夹并列,然后在resource文件夹创建META-INF.service文件夹,在该文件夹下创建接口的全限定名的文件,最后在文件内写入每个子类的全限定类名。

 代码非常简单

public interface SPIService {
    void execute();
}


public class SpiImpl1 implements SPIService {
    @Override
    public void execute() {
        Log.d("spi", "SpiImpl1 execute");
    }
}
    

ServiceLoader<SPIService> serviceLoader = ServiceLoader.load(SPIService.class);
        Iterator<SPIService> iterator = serviceLoader.iterator();
        while (iterator.hasNext()) {
            SPIService next = iterator.next();
            next.execute();
        }

四、流程图

五、源码学习

1、ServiceLoader.load(Class<T> class)

ServiceLoader.load()方法创建对象,ServiceLoader对象的构造方法是私有的, 不允许外部new创建对象,这样可以保证必要的参数,防止空指针问题。同时还有loadInstalled(Class<S> service)方法,支持加载系统接口类对象。

2、serviceLoader.iterator()

ServiceLoader实现iterator方法,这里是个迭代器设计模式。迭代器模式的使用场景是顺序遍历某个对象的内部元素,无需暴露内部的实现,实现解藕的目的。

3、iterator.hasNext()

iterator()返回一个iterator匿名内部类对象,hasNext()先判断LinkedHashMap集合中是否有创建好的实例,有就直接返回,没有就调用LazyIterator的hasNext方法,懒加载迭代器在使用时加载,因为会使用到反射和IO操作,对性能有点影响。

4、iterator.next()

同样next()会先判断LinkedHashMap集合中有没有数据,有就直接返回,没有就从LazyIterator.next()中读取。

知识点回顾:

1.迭代器模式,有遍历数据需求,迭代器模式将数据隔离到内部,解藕,提升拓展性和维护性。

2.内存-磁盘缓存模型,内存数据结构和和磁盘接口保持一致,先取内存,再取磁盘,保存到内存中,提升性能。

六、拓展

适用于调用方根据实际需求启用、扩展、替换服务的策略实现。

许多开源框架中都使用了 Java 的 SPI 机制,Android中美团WMRouter路由框架,java中javac注解处理器框架、JDBC 的 SPI 加载模式、日志框架 SLF4J 加载不同提供商的日志实现、Spring 中也大量适用了 SPI、Dubbo 的扩张机制、ServiceComb Java Chassis (CSE) 的 Filter、异常处理等扩展机制。

参考文献:

JAVA SPI 机制实现和原理分析 - 掘金

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值