Java SPI机制学习之开发实例
原创/朱季谦
在该文章正式开始前,先对 Java SPI是什么做一个简单的介绍。
SPI,是Service Provider Interface的缩写,即服务提供者接口,它允许开发人员定义一组接口,并由供应方或者第三方提供具体实现。这种机制能够让应用程序动态加载及执行各种接口实现。
根据名字来理解,比较抽象,举一个例子来说明。
假如,假如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一致的文件——
该com.zhu.service.UserService文件里写下com.zhu.service.impl.UserServiceImpl类名字——
这时候,就可以基于Java SPI动态加载到接口的实现类并执行了,我们写一个简单的测试类做验证——
public class Test {
public static void main(String[] args) {
ServiceLoader<UserService> serviceLoader = ServiceLoader.load(UserService.class);
for (UserService service : serviceLoader) {
service.getName();
}
}
}
执行该代码,ServiceLoader会加载到META-INF.services目录下的配置文件,找到对应接口全名文件,读取文件里的类名,再通过反射就可以进行实现类的实例化。既然能找到实现类的对象,那么不就可以基于父类引用指向子类对象,进而调用到实现类的getName()方法。该方法里执行打印语句 System.out.println("打印用户姓名"),打印结果如下,说明基于接口UserService,在程序动态加载并执行UserService接口实现。
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实现类的全名增加到文件里——
其他原有的代码无需改动,直接执行Test的main方法,打印结果如下,可以看到,新增的BUserServiceImpl实现类的getName()也被运行了。
这就说明,Java SPI机制会将文件里配置的所有实现类都动态加载运行,稍微思考了一下,不难发现,若当中某个实现类的getName()出现异常,那么后面还没有执行到的其他实现类就会终止了。
因此,Dubbo框架在设计SPI机制时,只是参考了Java SPI的实现,但没有照搬,相比Java,Dubbo增强了SPI机制,可以针对请求动态得选择需要的接口实现类来运行,更加灵活方便。我在自己的另一边原创博文中,详细介绍过Dubbo SPI的原理,感兴趣的小伙伴可以阅读——《Dubbo2.7的Dubbo SPI实现原理细节》
SPI机制的优点很明显,当我们需要基于已有接口新增一个实现类功能时,只需要新增一个实现类代码,无需在原有代码逻辑上做改动,就可以实现新增类的功能逻辑了。
这种场景比较适合在报表或者处理Excel文档情况下,需针对一个新报表或者Excel做相应定制化处理,只需要基于SPI已有接口新增一个实现类即可。我会在后续文章中,将过去应用到SPI的实践经验做一下总结。
Java SPI机制学习之开发实例的更多相关文章
- Java SPI机制学习笔记
最近在阅读框架源代码时,常常看到 SPI 的子包, 忍不住查了下: Service Provider Interface : 服务提供接口. JavaSPI 实际上是“基于接口的编程+策略模式+配置文 ...
- 组件化框架设计之Java SPI机制(三)
阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 本篇文章将从深入理解java SPI机制来介绍组件化框架设计: ...
- JAVA反射机制—学习总结
最近收到很多关于Java反射机制的问题留言,其实Java反射机制技术方面没有太多难点,或许是大家在学习过程中遗漏了细小知识点,导致一些问题无法彻底理解,现在我们简单的总结一下,加深印象.什么是反射机制 ...
- Java spi机制浅谈
最近看到公司的一些框架和之前看到的开源的一些框架的一些服务发现和接入都采用了java的spi机制. 所以简单的总结下java spi机制的思想. 我们系统里抽象的各个模块,往往有很多不同的实现方案,比 ...
- Java SPI 机制实现解耦与本地化
SPI 是 Java 提供的一种服务加载方式,全名为 Service Provider Interface,可以避免在 Java 代码中写死服务的提供者,而是通过 SPI 服务加载机制进行服务的注册和 ...
- JDK源码解析之Java SPI机制
1. spi 是什么 SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件. 系统设计的各个抽象,往往 ...
- 聊聊Java SPI机制
一.Java SPI机制 SPI(Service Provider Interface)是JDK内置的服务发现机制,用在不同模块间通过接口调用服务,避免对具体服务服务接口具体实现类的耦合.比如JDBC ...
- Java SPI机制实战详解及源码分析
背景介绍 提起SPI机制,可能很多人不太熟悉,它是由JDK直接提供的,全称为:Service Provider Interface.而在平时的使用过程中也很少遇到,但如果你阅读一些框架的源码时,会发现 ...
- Java反射机制可以动态修改实例中final修饰的成员变量吗?
问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...
- Java SPI机制详解
Java SPI机制详解 1.什么是SPI? SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制.SPI是一种动态替换发现的机制, 比如有个 ...
随机推荐
- Mac装机必备软件2023
码农一枚,Mac作为生产力工具已经有10多年了. 用Mac的原因除了系统清爽,逼格高之外,最主要还是因为作为一个资深全栈,要做Apple相关开发,必须用MacOS系统. 与Windows不同, ...
- Pandas:在DataFrame中添加一行,并设置行索引
解决方案 效果图 参考链接 https://blog.csdn.net/Caiqiudan/article/details/107788525
- 线上问题排查--进程重启失败,最后发现是忘了cd
背景 我前面写了几篇文章,讲c3p0数据库连接池发生了连接泄露,但是随机出现,难以确定根因,最终呢,为了快速解决问题,我是先写了个shell脚本,脚本主要是检测服务的接口访问日志,看看过去的30s内是 ...
- 青少年CTF平台-Web-Robots
题目信息 题目名称:Robots 题目描述:昨天十三年社团讲课,讲了Robots.txt的作用,小刚上课没有认真听课正在着急,你能不能帮帮忙? 题目难度:一颗星 解题过程 访问题目链接 在这里插入图片 ...
- struct(C# 参考)
struct 类型是一种值类型,通常用来封装小型相关变量组,例如,矩形的坐标或库存商品的特征. 下面的示例显示了一个简单的结构声明. 1 public struct Book 2 { 3 public ...
- idea 热部署插件 JRebel 安装
idea 热部署插件 JRebel 安装 1.安装 直接在idea 插件搜索安装 JRebel and XRebel 安装,安装后需要破解才能使用 2.破解 破解原来需要远程连接服务器破解或者下载源码 ...
- 《CTFshow-Web入门》07. Web 61~70
@ 目录 web61~65 题解 web66 题解 原理 web67 题解 原理 web68 题解 原理 web69 题解 原理 web70 题解 原理 ctf - web入门 web61~65 题解 ...
- API接口设计规范,看这篇就足以了
优秀的设计是产品变得卓越的原因.设计API意味着提供有效的接口,可以帮助API使用者更好地了解.使用和集成,同时帮助人们有效地维护它.每个产品都需要使用手册,API也不例外. 在API领域,可以将 ...
- .NET6.0实现IOC容器
.NET6.0实现IOC容器 IOC的作用这里省略-只对如何使用进行说明. 1. 创建一个.NET6应用程序 这里使用 .NET6.0 WebAPI 应用 2. 声明接口 public interfa ...
- 聊聊数据库事务内嵌TCP连接
最近再看项目代码,发现很多的service里面,喜欢在事务内部再去调用HTTP请求,简单分析下此种方式的利弊与解决策略. 概述 在数据库内部嵌套TCP连接(一般是HTTP调用或是RPC远程调用). @ ...