首页 > 图灵资讯 > 技术篇>正文

由浅入深学习Java SPI机制

2023-04-02 17:46:07

SPI(Service Provider Interface),是JDK提供内置服务的发现机制可以理解为运行时动态加载接口的实现类本文带大家由浅入深学习Java SPI机制

SPI可用于框架扩展和更换组件,主要用于框架开发人员,如java.sql.对于Driver接口,其他不同的制造商可以对同一接口做出不同的实现,MySQLPostgreSQL为用户提供不同的实现,Java的SPI机制可以为某个接口找到服务。一旦代码涉及到特定的实现类别,它就违反了可拔插的原则。如果需要替换一个实现,则需要修改代码。为了在模块组装过程中不动态指示,需要一种服务发现机制

JavaSPI机制的主要思想是将组装控制权转移到程序之外。这种机制在模块化设计中尤为重要,其核心思想是解耦。理解可以结合下图来理解SPI机制:

标准化接口+战略模式+配置文件

从上图中,我们可以清楚地知道SPI的三个部分:界面+实现类+配置文件;因此,如果SPI机制应用于项目中,则需要遵循以下协议:

1.当服务提供商提供接口的具体实现时,在METAjar包-INF创建/services目录“界面全限定名”命名文件的内容是实现类的全限定名。

2.主程序通过java.util.Serviceloder动态装载实现模块,通过扫描META-INF/services目录下的配置文件找到实现类的全限定名,并将类加载到JVM;

SPI和API的区别:

API是调用并用于实现目标的类别、界面、方法等的描述;

SPI是扩展和实现目标的类别、界面、方法等的描述;

换句话说,API 为操作提供特定的类别和方法,SPI 符合特定类别和方法的操作。

让我们通过实例进一步了解SPI:

定义接口:

package com.cainiao.ys.spi.learn;

import java.util.List;

public interface Search {

public List searchDoc(String keyword);

}

实现文件搜索:

package com.cainiao.ys.spi.learn;

import java.util.List;

public class FileSearch implements Search{

@Override

public List searchDoc(String keyword) {

System.out.println("文件搜索 "+keyword);

return null;

}

}

实现数据库搜索

package com.cainiao.ys.spi.learn;

import java.util.List;

public class DatabaseSearch implements Search{

@Override

public List searchDoc(String keyword) {

System.out.println("数据搜索 "+keyword);

return null;

}

}

使用 ServiceLoader 加载配置文件中指定的实现:

package com.vivo.study.spidemo.test

import java.util.ServiceLoader;

import com.vivo.study.spidemo.spi.HelloSPI;

public class SPIDemo {

public static void main(String[] args) {

ServiceLoader serviceLoader = ServiceLoader.load(HelloSPI.class);

// 实施不同厂家的业务实现,并根据业务需要进行具体配置

for (HelloSPI helloSPI : serviceLoader) {

helloSPI.sayHello();

}

}

}

输出结果:

Image Hello

Text Hello

当然,SPI机制也有一些缺点:

1.不能按需加载,需要经历所有的实现,并实例化,然后在循环中找到我们需要的实现。如果你不想使用一些实现类,或者一些实现类非常耗时,它也被包含和实例化,这就造成了浪费。

2.获取实现类的方法不够灵活,只能通过 Iterator 形式获取,不能根据参数获得相应的实现类。

3.使用多个并发多线程 ServiceLoader 类的例子是不安全的。

最后,不难发现,只要用户能够按照系统规则进行定义,并且能够注册到系统中的功能点,就有SPI思想。为了避免缺乏SPI机制,我们在在选择SPI机制时,可以考虑使用dubo实现的SPI机制。想要更深入学习javaSPI学生可以查阅资料,观看相关视频课程,让自己有更好的学习体验。

上一篇 总结Java反射面试题(附答案)
下一篇 常考Struts2面试题(附答案)

文章素材均来源于网络,如有侵权,请联系管理员删除。