当前位置 : 主页 > 编程语言 > java >

软件设计模式学习——介绍SPI

来源:互联网 收集:自由互联 发布时间:2022-08-15
推荐两本书:《架构修炼之道》和《软件框架设计的艺术》 SPI是一种回调的思想,回调是指我们在使用api时,我们可以向api传入一个类或者方法,api在合适的时间调用类或者方法。SP


推荐两本书:《架构修炼之道》和《软件框架设计的艺术》
SPI是一种回调的思想,回调是指我们在使用api时,我们可以向api传入一个类或者方法,api在合适的时间调用类或者方法。SPI是在一些通用的标准中,为标准的实现产商提供的扩展点。标准在上层提供API,API内部使用了SPI,当API被客户使用时,会动态得从当前运行的classpath中寻找该SPI的实现,然后使用该SPI的实现来完成API的功能。
“SPI”,全程为:service provider interface,“SPI”的规则如下:
概念上更依赖调用方。
组织上位于调用方所在的包中。
实现位于独立的包中。
常见的例子是:插件模式的插件。

“API”的规则如下:

概念上更接近实现方。
组织上位于实现方所在的包中。
实现和接口在一个包中。

软件设计模式学习——介绍SPI_开发语言


二、SPI的机制和原理

2.1 SPI的机制

Service provider提供Interface的具体实现后,在目录META-INF/services下的文件(以Interface全路径命名)中添加具体实现类的全路径名;

接口实现类的jar包存放在所使用的类加载器能找到的地方。

应用程序使用ServiceLoader动态加载实现类(根据目录META-INF/services下的配置文件找到实现类的全限定名并调用classloader来加载实现类到JVM);

SPI的实现类必须具有无参数的构造方法。

SPI加载的核心就是ClassLoader的getResource系列方法,jdk提供了一个工具类,就是上面说的ServiceLoader。

2.2 SPI原理

(1)应用程序调用 ServiceLoader.load 方法,ServiceLoader.load 方法内先创建一个新的ServiceLoader,并实例化该类中的成员变数,包括:

ClassLoader loader(类载入器)

AccessControlContext acc(访问控制器)

LinkedHashMap<String, S> providers(用于缓存载入成功的类)

LazyIterator lookupIterator(实现迭代器功能)

(2) 应用程序通过迭代器获取对象实例

ServiceLoader 先判断成员变量 providers 对象中否有缓存实例对象,如果有缓存,直接返回。

如果没有缓存,执行类的装载:读取 META-INF/services/ 下的配置文件,获得所有能被实例化的类的名称,通过反射方法 Class.forName() 载入类对象,并用 instance() 方法将类实例化。把实例化后的类缓存到providers 对象中然后返回实例对象。


网友评论