Java SPI机制总结系列之开发入门实例

news2024/11/20 20:23:54

 

原创/朱季谦

在该文章正式开始前,先对 Java SPI是什么做一个简单的介绍。

SPI,是Service Provider Interface的缩写,即服务提供者接口,单从字面上看比较抽象,你可以理解成,该机制就像Spring容器一样,通过IOC将对象的创建交给了Spring容器处理,若需要获取某个类的对象,就从Spring容器里取出使用即可。同理,在SPI机制当中,提供了一个类似Spring容器的角色,叫【服务提供者】,在代码运行过程中,若要使用到实现了某个接口的服务实现类对象,只需要将对应的接口类型交给服务提供者。服务提供者将会动态加载实现了该接口的所有服务实现类对象。
服务提供者的角色用下图来表示。

image

举一个例子来说明。

假如,假如Maven项目里有这样一个interface接口,接口全名“com.zhu.service.UserService”——

package com.zhu.service;

public interface UserService {
    void getName();
}

创建一个“com.zhu.service.impl.AUserServiceImpl”实现类——

public class AUserServiceImpl implements UserService {
    @Override
    public void getName() {
        System.out.println("这是A用户姓名");
    }
}

接着在resource资源里,创建一个META-INF.services目录,在该目录里,创建一个文件名与接口com.zhu.service.UserService一致的文件——

image

该com.zhu.service.UserService文件里写下com.zhu.service.impl.UserServiceImpl类名字——

image

这时候,就可以基于Java SPI动态加载到接口的实现类并执行了,我们写一个简单的测试类做验证——

public class Test {
    public static void main(String[] args) {
    ServiceLoader<UserService> serviceLoader = ServiceLoader.load(UserService.class);
    Iterator<UserService> serviceIterator = serviceLoader.iterator();
    while (serviceIterator.hasNext()) {
         UserService service = serviceIterator.next();
         service.getName();
    }
}
    }
}

执行该代码,ServiceLoader会加载到META-INF.services目录下的配置文件,找到对应接口全名文件,读取文件里的类名,再通过反射就可以进行实现类的实例化。既然能找到实现类的对象,那么不就可以基于父类引用指向子类对象,进而调用到实现类的getName()方法。该方法里执行打印语句 System.out.println("打印用户姓名"),打印结果如下,说明基于接口UserService,在程序动态加载并执行UserService接口实现。

image

Java SPI的机制玩法,就如上文这一整个过程的实现。

该机制存在一个缺陷,假如该接口对应的文件存在多份实现类,那么,它都会一起执行了。

我们增加多一个实现类BUserServiceImpl——

public class BUserServiceImpl implements UserService {
    @Override
    public void getName() {
        System.out.println("这是B用户姓名");
    }
}

然后,在resource资源里的META-INF.services目录接口对应com.zhu.service.UserService文件里,将BUserServiceImpl实现类的全名增加到文件里——

image

其他原有的代码无需改动,直接执行Test的main方法,打印结果如下,可以看到,新增的BUserServiceImpl实现类的getName()也被运行了。

image

这就说明,Java SPI机制会将文件里配置的所有实现类都动态加载运行,稍微思考了一下,不难发现,若当中某个实现类的getName()出现异常,那么后面还没有执行到的其他实现类就会终止了。

因此,Dubbo框架在设计SPI机制时,只是参考了Java SPI的实现,但没有照搬,相比Java,Dubbo增强了SPI机制,可以针对请求动态得选择需要的接口实现类来运行,更加灵活方便。我在自己的另一边原创博文中,详细介绍过Dubbo SPI的原理,感兴趣的小伙伴可以阅读——《Dubbo2.7的Dubbo SPI实现原理细节》

SPI机制的优点很明显,当我们需要基于已有接口新增一个实现类功能时,只需要新增一个实现类代码,无需在原有代码逻辑上做改动,就可以实现新增类的功能逻辑了。

这种场景比较适合在报表或者处理Excel文档情况下,需针对一个新报表或者Excel做相应定制化处理,只需要基于SPI已有接口新增一个实现类即可。我会在后续文章中,将过去应用到SPI的实践经验做一下总结。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1384101.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Baumer工业相机堡盟工业相机如何使用OpenCV实现相机图像的显示(C#)

Baumer工业相机堡盟工业相机如何使用OpenCV实现相机图像的显示&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机的图像转换为OpenCV的Mat图像的技术背景在NEOAPI SDK里使用OpenCV实现相机图像的显示联合OpenCV实现相机图像的显示测试演示图 工业相机通过使用OpenCV实现…

【QML COOK】- 008-自定义属性

前面介绍了用C定义QML类型&#xff0c;通常在使用Qt Quick开发项目时&#xff0c;C定义后端数据类型&#xff0c;前端则完全使用QML实现。而QML类型或Qt Quick中的类型时不免需要为对象增加一些属性&#xff0c;本篇就来介绍如何自定义属性。 1. 创建项目&#xff0c;并编辑Ma…

Minio安装及整合SpringBoot

一. MinIO概述 官网地址&#xff1a;https://minio.org.cn MinIO是一款基于Apache License v2.0开源协议的分布式文件系统&#xff08;或者叫对象存储服务&#xff09;&#xff0c;可以做为云存储的解决方案用来保存海量的图片、视频、文档等。由于采用Golang实现&#xff0c;服…

细说JavaScript语句详解

一、顺序结构 二、表达式语句 三、声明语句 四、条件语句 1、if语句 2、if…else语句 3、else if语句 4、switch语句 五、循环语句 1、while循环 2、do… while循环 3、for循环 4、for…in循环 六、跳出语句 1、label语句 2、break语句 3、continue语句

Go interface基础

接口类型是对其它类型行为的概括与抽象。通过使用接口&#xff0c;我们可以写出更加灵活和通用的函数&#xff0c;这些函数不用绑定在一个特定的类型实现上。 很多面向对象的语言都有接口这个概念&#xff0c;Go 语言的接口的独特之处在于它是隐式实现。换句话说&#xff0c;对…

在illustrator中按大小尺寸选择物体 <脚本 018>

在Illustrator中我们可以依据对象的属性 如:填充颜色、描边颜色或描边宽度来选择相同属性的对象,但是Illustrator中没有根据不同大小尺寸来选择对象的功能,下面介绍的就是根据大小尺寸选择对象的脚本。 1、下面是当前画板中的所有对象,我们想把一些在尺寸小一些的方形物体…

Zung氏焦虑症测试SAS

SAS被称为焦虑自评量表&#xff0c;是一种用来测量焦虑症状程度以及观察治疗过程中变化情况的心理量表。主要用于评估心理状态&#xff0c;辅助参考数据&#xff0c;也是焦虑评定的标准。焦虑自评量表系是由William W.K. Zung编制的&#xff0c;该量表已成为心理咨询师、心理医…

UDS 诊断通讯

UDS有哪些车型支持 UDS(统一诊断服务)协议被广泛应用于汽车行业中,支持多种车型。具体来说,UDS协议被用于汽车电子控制单元(ECU)之间的通讯,以实现故障诊断、标定、编程和监控等功能。 支持UDS协议的车型包括但不限于以下几种: 奥迪(Audi)车型:包括A3、A4、A5、A6…

C++学习笔记——SLT六大组件及头文件

目录 一、C中STL&#xff08;Standard Template Library&#xff09; 二、 Gun源代码开发精神 三、 实现版本 四、GNU C库的头文件分布 bits目录 ext目录 backward目录 iostream目录 stdexcept目录 string目录 上一篇文章&#xff1a; C标准模板库&#xff08;STL&am…

memory泄露分析方法(java篇)

#memory泄露主要分为java和native 2种&#xff0c;本文主要介绍java# 测试每天从monkey中筛选出内存超标的app&#xff0c;提单流转到我 首先&#xff0c;辨别内存泄露类型&#xff08;java&#xff0c;还是native&#xff09; 从采到的dumpsys_meminfo_pid看java heap&…

IPv6组播--SSM Mapping

概念 SSM(Source-Specific Multicast)称为指定源组播,要求路由器能了解成员主机加入组播组时所指定的组播源。 如果成员主机上运行MLDv2,可以在MLDv2报告报文中直接指定组播源地址。但是某些情况下,成员主机只能运行MLDv1,为了使其也能够使用SSM服务,组播路由器上需要提…

【用法总结】无障碍AccessibilityService

一、背景 本文仅用于做学习总结&#xff0c;转换成自己的理解&#xff0c;方便需要时快速查阅&#xff0c;深入研究可以去官网了解更多&#xff1a;官网链接点这里 之前对接AI语音功能时&#xff0c;发现有些按钮&#xff08;或文本&#xff09;在我没有主动注册唤醒词场景…

【手搓深度学习算法】用逻辑回归分类Iris数据集-线性数据篇

用逻辑回归分类Iris数据集-线性数据篇 前言 逻辑斯蒂回归是一种广泛使用的分类方法&#xff0c;它是基于条件概率密度函数的最大似然估计的。它的主要思想是将输入空间划分为多个子空间&#xff0c;每个子空间对应一个类别。在每个子空间内部&#xff0c;我们假设输入变量的取…

肯·汤普逊 :我心目中的神,好像真正无敌之上的大佬都对C++提出了批判!大佬们的思想像红太阳太耀眼,常人不能直视

肯尼斯蓝汤普逊&#xff08;英语&#xff1a;Kenneth Lane Thompson&#xff0c;1943年2月4日—&#xff09;&#xff0c;小名肯汤普逊&#xff08;英语&#xff1a;Ken Thompson&#xff09;&#xff0c;美国计算机科学学者和工程师。黑客文化圈子通常称他为“ken”[1]。在贝尔…

NLP论文阅读记录 - 2021 | WOS 使用深度强化学习及其他技术进行自动文本摘要

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作2.1. Seq2seq 模型2.2.强化学习和序列生成2.3.自动文本摘要 三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结思考 前言 Auto…

Keil5如何生成反汇编文件

Keil5如何生成反汇编文件 在Keil5界面下点击选项&#xff0c;选择“User”&#xff0c;勾选“After Build/Rebuild”中“RUN #1”&#xff0c;复制fromelf --text -a -c --outputxxx.dis xxx.axf 在Linker栏中找到“Linker Control string”里最后-o后的.axf文件&#xff0c;将…

对资金类服务幂等设计与测试的思考

之前写过一篇《系统设计的幂等性》科普文章。 幂等性原本是数学上的概念&#xff0c;用在接口上就可以理解为&#xff1a;同一个接口&#xff0c;多次发出同一个请求&#xff0c;必须保证操作只执行一次。调用接口发生异常并且重复尝试时&#xff0c;总是会造成系统所无法承受的…

lenovo联想笔记本电脑拯救者Legion Y7000 2019 PG0(81T0)原装出厂Windows10系统

链接&#xff1a;https://pan.baidu.com/s/1fn0aStc4sfAfgyOKtMiCCA?pwdas1l 提取码&#xff1a;as1l 联想拯救者原厂Win10系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、Office办公软件、联想电脑管家等预装程序 所需要工具&#xff1a;…

响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例4-1 表单

代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>表单</title> </head><body> <!--<form action"URL地址" method"提交方式" name"表单名称" /*编码“多部…

数据在AI图像修复任务中的核心作用

在人工智能&#xff08;AI&#xff09;领域&#xff0c;数据的重要性不言而喻。尤其在图像修复任务中&#xff0c;数据的精度和质量直接影响着AI模型的性能。图像修复是指利用AI技术自动识别图像中的缺陷或遮挡物&#xff0c;并对其进行修复或还原的过程。这项技术广泛应用于各…