java中spi有什么作用,jdk的spi机制

java中spi有什么作用,jdk的spi机制,一文搞懂Java的SPI机制(推荐)

Java定义了一组JDBC接口,但没有提供具体的实现类。相反,它在不同云供应商提供的数据库中实现包。本文介绍了Java的SPI机制。有兴趣的朋友来看看吧。

目录

1简介缺点源代码应用场景插件扩展案例

1 简介

SPI,服务提供者接口,是一种服务发现机制。

通过SPI,服务接口可以从服务实现中分离出来:

服务提供商(如springboot starter)提供SPI接口。作为服务提供者,当你无法形成绝对规范的强制力时,明智的做法是适度‘放权’,让客户端适当定制实现。

客户端(常见的springboot项目)可以以本地注册的形式向服务器注册实现类,轻松实现可插拔性。

缺点

无法按需加载。

虽然ServiceLoader有延迟加载,但是只能通过遍历得到全部。如果有些实现类比较耗时,而你又不需要加载,那就是资源浪费。获取实现类的方式不够灵活,只能通过迭代器获取。

Duospi实现模式优化了以上两点。

源码

应用程序通过迭代器接口获得对象实例。这里,它将首先确定providers对象中是否有实例对象:

有实例,然后返回。

不,执行类加载步骤。具体的类加载实现如下:

LazyIterator#hasNextService读取META-INF/services下的配置文件,获取所有可以实例化的类的名称,完成SPI配置文件的分析。

LazyIterator#nextService负责实例化hasNextService()读取的实现类,并将实例化的对象存储在providers集合中进行缓存。

使用

如果一个接口有三个实现类,那么系统运行时接口选择哪个实现类?

那么就需要SPI,根据指定或默认配置,找到对应实现类,加载进来,然后使用该实现类实例

当系统如下运行时,加载配置并用实现A2实例化一个对象以提供服务:

再比如,如果你想通过jar包提供一个接口的实现,只需要在你自己的jar包的META-INF/services/目录中放一个与接口同名的文件,并指定接口的实现是你自己的jar包中的一个类:

当其他人使用这个接口,然后使用您的jar包时,他们会在运行时通过您的jar包规范文件找到哪个实现类用于这个接口。这是JDK的内置功能。

我就不在META-INF/services下定义了好吗?只是想在别的地方定义一下,好吗?

不要!JDK已经指定了配置路径。随便定义的话,类加载器就不知道从哪里加载了。

假设你有一个项目P,一个接口A,A在P中没有实现类,在系统运行的时候,如何为A选择实现类?

您可以制作自己的jar包META-INF/services/,并放入一个带有接口名称的文件。接口A的实现类=com . javaedge . service . implementation类A2。

让P依赖你的jar包。系统运行时,P运行。对于接口A,它将扫描依赖的jar包以查看是否有META-INF/services文件夹:

是的,查看名为interface A的文件:是的,在您的jar包中查找指定接口A的实现是哪个类。

适用场景

插件扩展

比如你开发一个开源框架,如果你想让别人自己写插件,把它们安排在你的开源框架里,扩展功能。

比如JDBC。Java定义了一组JDBC接口,但没有提供具体的实现类。相反,它在不同云供应商提供的数据库中实现包。

但是当项目运行时,应该使用JDBC接口的哪些实现类呢?

一般要根据你使用的数据库来驱动jar包,比如MySQL,这是我们最常用的一个。有:

当系统运行到您的JDBC接口时,它将使用您在底层引入的jar中提供的实现类。

案例

例如,Sharding-jdbc数据加密模块支持AES和MD5加密方法。但是如果客户端不想用内置的两种加密,而是想用RSA算法呢?有必要每增加一个算法就发一个版本的sharding-jdbc吗?

分片-jdbc不可能这么蠢。首先提供EncryptAlgorithm接口,并引入SPI机制将服务接口与服务实现分离。

如果客户端要使用自定义加密算法,只需要在客户端项目META-INF/services的路径下定义接口的全限定名文件,并在文件中写入加密实现类的全限定名即可。

这显示了SPI的优势:

客户端(自己的项目)提供了服务器的接口自定义实现(sharding-jdbc),但是和服务器状态是分离的,只有在客户端提供自定义接口实现的时候才会加载,其他都不相关;添加或删除客户端的实现类不会影响服务器。

如果客户端不想要RSA算法,想用内置的AES算法,可以随时删除实现类,扩展性强,插件式架构。

关于理解Java的SPI机制的这篇文章到此为止。有关Java SPI机制的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望你以后能支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • ubuntu18.04安装jdk8,ubuntu中安装jdk
  • ubuntu18.04安装jdk8,ubuntu中安装jdk,Ubuntu 安装 JDK8 的两种方法(总结)
  • JDK1.8安装教程,安装配置jdk1.8
  • JDK1.8安装教程,安装配置jdk1.8,2020JDK1.8安装教程详解(一次就可安装成功)
  • ,,jdk8使用stream实现两个list集合合并成一个(对象属性的合并)
  • ,,IntelliJ IDEA之配置JDK的4种方式(小结)
  • java代理模式详解,java代理模式的典型例子,java代理模式(jdk proxy)
  • java中spi有什么作用,jdk的spi机制,一文搞懂Java的SPI机制(推荐)
  • ,,详解JDK自带javap命令反编译class文件和Jad反编译class文件(推荐使用jad)
  • ,,JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版整理
  • ,,JAVA JDK8 List分组的实现和用法
  • idea配置tomcat和jdk,idea配置本地gradle
  • 简单叙述一下jdk环境变量的配置,jdk环境变量配置是干什么的
  • 建立Java开发环境,安装JDK,一般需要设置环境变量,在安装完JDK后,需要在环境变量中配置
  • centos7安装jdk,centos如何安装java
  • 留言与评论(共有 条评论)
       
    验证码: