原创/朱季谦

在该文章正式开始前,先对 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机制学习之开发实例的更多相关文章

  1. Java SPI机制学习笔记

    最近在阅读框架源代码时,常常看到 SPI 的子包, 忍不住查了下: Service Provider Interface : 服务提供接口. JavaSPI 实际上是“基于接口的编程+策略模式+配置文 ...

  2. 组件化框架设计之Java SPI机制(三)

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 本篇文章将从深入理解java SPI机制来介绍组件化框架设计: ...

  3. JAVA反射机制—学习总结

    最近收到很多关于Java反射机制的问题留言,其实Java反射机制技术方面没有太多难点,或许是大家在学习过程中遗漏了细小知识点,导致一些问题无法彻底理解,现在我们简单的总结一下,加深印象.什么是反射机制 ...

  4. Java spi机制浅谈

    最近看到公司的一些框架和之前看到的开源的一些框架的一些服务发现和接入都采用了java的spi机制. 所以简单的总结下java spi机制的思想. 我们系统里抽象的各个模块,往往有很多不同的实现方案,比 ...

  5. Java SPI 机制实现解耦与本地化

    SPI 是 Java 提供的一种服务加载方式,全名为 Service Provider Interface,可以避免在 Java 代码中写死服务的提供者,而是通过 SPI 服务加载机制进行服务的注册和 ...

  6. JDK源码解析之Java SPI机制

    1. spi 是什么 SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件. 系统设计的各个抽象,往往 ...

  7. 聊聊Java SPI机制

    一.Java SPI机制 SPI(Service Provider Interface)是JDK内置的服务发现机制,用在不同模块间通过接口调用服务,避免对具体服务服务接口具体实现类的耦合.比如JDBC ...

  8. Java SPI机制实战详解及源码分析

    背景介绍 提起SPI机制,可能很多人不太熟悉,它是由JDK直接提供的,全称为:Service Provider Interface.而在平时的使用过程中也很少遇到,但如果你阅读一些框架的源码时,会发现 ...

  9. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

  10. Java SPI机制详解

    Java SPI机制详解 1.什么是SPI? SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制.SPI是一种动态替换发现的机制, 比如有个 ...

随机推荐

  1. 文心一言 VS 讯飞星火 VS chatgpt (64)-- 算法导论6.5 3题

    文心一言 VS 讯飞星火 VS chatgpt (64)-- 算法导论6.5 3题 三.要求用最小堆实现最小优先队列,请写出 HEAP-MINIMUM.HEAP-EXTRACT-MIN.HEAP DE ...

  2. clickhouse 与 zookeeper

    目录 clickhouse 设置中的 zookeeper 配置 参数说明 配置示例 [预发生产] ClickHouse Keeper 四字母命令 clickhouse 设置中的 zookeeper 配 ...

  3. git关于分支的常用命令

    上家公司实习,一个人干一个项目,没有用git管理代码,导致我以前学的命令都忘了 git checkout -b xxx 创建xxx分支 并切换到xxx分支 等价于 git branch xxx git ...

  4. 看,这些 plugins 常用又简单

    前面文章中 体验了webpack的打包 .解析css资源 .处理图片字体等文件 接下来看看 plugins 有什么作用吧~ 项目路径如下,和上一篇 处理图片字体等文件 项目保持一致 demo ├─ s ...

  5. Cilium系列-16-CiliumNetworkPolicy 实战演练

    系列文章 Cilium 系列文章 前言 今天我们进入 Cilium 安全相关主题, 基于 Cilium 官方的<星球大战> Demo 做详细的 CiliumNetworkPolicy 实战 ...

  6. html5 3.0 表单

    表单的定义:多个输入框,以表格的形式展示 表单常用在网页登录和注册功能中 表单的元素属性:<input type="text"name="   "valu ...

  7. 使用Java来开发物联网应用

    这是Hello, Lithosphere Tutorials系列教程中的其中一篇. 感觉介绍用C/C++,用Python来开发物联网应用的文章比较多,用Java来做物联网的文章比较少. 这篇文章,介绍 ...

  8. Shiro配置类中的各个配置项浅谈

    背景: 上文中在落地实践时,对Shiro进行了相关的配置,并未对其含义作用进行详细学习,本章将进一步详解其作用含义. Shiro配置类中的各个配置项的作用: @Bean public Security ...

  9. 细谈商品详情API接口设计

    一.引言 随着互联网技术的发展,商品详情信息的展示和交互变得越来越重要.为了提供更好的用户体验,我们需要设计一套高效.稳定且易于扩展的商品详情API接口.本文将详细探讨商品详情API接口的设计,包括接 ...

  10. 深入了解API接口调用——从获取淘宝商品数据开始

    API(Application Programming Interface)是现代软件开发中常用的一种技术,它允许不同的软件系统进行交互和通信.在本文中,我们将深入探讨如何通过API接口来获取淘宝商品 ...