java热插拔组件 SPI机制

news2024/11/25 10:35:16

文章目录

  • 前言
  • 一、热插拔(spi机制)是什么?
  • 二、使用步骤
    • 1.利用java META-INF
    • 2.利用google spi
    • 3. 测试效果
  • 总结


前言

在项目中,如果想要增加项目的灵活性,健壮性, 高逼格,那么你要对于java中的一些机制有了解;
例如:

  • java中的spi机制
  • spring中的spring.factories 等

这里重点说明spi机制,其实 spring中的spring.factories文件与spi机制类似,这里给大家留个小作业,去自己看吧~


一、热插拔(spi机制)是什么?

SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制,可以轻松实现面向服务的注册与发现,完成服务提供与使用的解耦,并且可以实现动态加载。
  引入服务提供者就是引入了SPI接口的实现者,通过本地的注册发现获取到具体的实现类,轻松可插拔,SPI实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载,为某个接口寻找服务实现的机制。

说人话就是:

通过它可以实现 某个接口的策略灵活选择一个实现类,并且可以利用更改配置文件,或者选择内容的机制(甚至通过程序改变), 无需重启服务,即可切换实现类,完成 “热插拔”,像使用一些组件一样,灵活添加,卸载掉 功能实现类;

以程序中常见的, 策略模式为例:

  1. 登录接口
  2. 登录接口实现类: 手机登录(1) 用户名密码登录(2) 邮箱登录(3)
  3. 项目中三个实现类都有,多个环境部署给不同用户, 要求如下
  4. A 环境采用 1 2 登录, B环境采用 2 登录, C 环境采用 23 登录 ,D 环境采用 123 登录

展示吧~~ 咋弄吧? 一个环境一个环境的改代码? 把多余的实现类删掉?
这里就可以通过spi机制,灵活的配置每个环境的实现类,达到上述要求

二、使用步骤

1.利用java META-INF

  1. 创建接口
// 接口
public interface SpiService {
    void sout();
}
  1. 创建实现类
// 实现类
public class SpiServiceImpl implements SpiService {
    @Override
    public void sout() {
        System.out.println("SpiServiceImpl 被调用");
    }
}
  1. 在resource文件夹下创建文件夹(META-INF.services)以及文件
    • 文件名称 接口全路径 : com.pdf.word.service.SpiService
    • 文件内容 接口实现类全路径 : com.pdf.word.service.impl.SpiServiceImpl
      文件夹以及文件

2.利用google spi

  1. 创建接口
public interface GoogleSpiService {
    void sout();
}
  1. 创建实现类
  2. 引入google,在实现类上加入@AutoService(接口.class)
@AutoService(GoogleSpiService.class)
public class GoogleSpiServiceImpl implements GoogleSpiService {
    @Override
    public void sout() {
        System.out.println("GoogleSpiService 被调用");
    }
}

3. 测试效果

创建一个测试类

class SpiServiceTest {

    public static void main(String[] args) {
        /**---------------------------利用java META-INF ----------------------------------------**/
        ServiceLoader<SpiService> load = ServiceLoader.load(SpiService.class);
        List<SpiService> spiServiceList = load.stream().map(ServiceLoader.Provider::get).toList();
        for (SpiService spiService : spiServiceList) {
            spiService.sout();
        }
        /**---------------------------利用google spi ----------------------------------------**/
        ServiceLoader<GoogleSpiService> load1 = ServiceLoader.load(GoogleSpiService.class);
        List<GoogleSpiService> spiServiceList1 = load1.stream().map(ServiceLoader.Provider::get).toList();
        for (GoogleSpiService spiService : spiServiceList1) {
            spiService.sout();
        }
    }

}

运行后,打印如下:
运行结果

总结

通过两种方式都可以实现spi机制的调用,这里展示简单调用,当项目中有多个实现类的时候,就可以灵活多变的实现热插拔效果了~

  • 利用java META-INF
    想用哪个,哪些实现类,就在文件中写哪些实现类的类全路径,每个实现类独占一行
  • 利用google spi
    想用哪个,哪些实现类,就在相应的实现类上加注解就行了

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

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

相关文章

QtCreator ui设置界面 Layout 的属性 layoutStretch

layoutStretch 用于控制Layout在被用户进行缩放时。里面控件的缩放比例。如一个水平布局里面有两个控件 一个 QLineEdit 和 QPushButton。首先将两个控件的尺寸策列的水平策略都设置为Expanding。此时在将包含这两个控件的水平布局的 layoutStretch 进行如下设置。 运行程序就…

权衡与选择:如何巧妙管理项目需求的优先级

在项目管理领域&#xff0c;处理和管理需求可能是最具挑战性的环节之一。每一个项目都充满了各种需求&#xff0c;从业务需求到技术需求&#xff0c;从用户需求到系统需求。而如何有效地为这些需求排列优先级&#xff0c;不仅会影响项目的进度和资源分配&#xff0c;还会直接关…

Azure创建第一个虚拟机

首先&#xff0c;登录到 Azure 门户 (https://portal.azure.com/)。在 Azure 门户右上角&#xff0c;点击“虚拟机”按钮&#xff0c;并点击创建&#xff0c;创建Azure虚拟机。 在虚拟机创建页面中&#xff0c;选择所需的基本配置&#xff0c;包括虚拟机名称、操作系统类型和版…

threejs纹理的使用

实现地板的效果&#xff0c;需要导入3张图片&#xff0c;第一种样式&#xff0c;第二种&#xff0c;木板间的间隙&#xff0c;第三种&#xff0c;木板的粗细图片。先注册一个物体属性&#xff0c;在物体属性上加上图片&#xff0c;注册代码如下图&#xff1a; const floorMat …

乡村振兴指数与其30余个原始变量数据(2000-2022年)

乡村振兴是当下经济学研究的热点之一&#xff0c;对乡村振兴进行测度&#xff0c;是研究基础。测度乡村振兴水平的学术论文广泛发表在《数量经济技术经济研究》等顶刊上。整理了2000-2022年城市层面的乡村振兴指数与其30余个原始变量数据&#xff0c;供大家使用。 数据来源&…

大数据Flink(六十二):批处理的入门案例

文章目录 批处理的入门案例 一、示例 二、​​​​​​​开发步骤

Ae 效果:CC Environment

透视/CC Environment Perspective/CC Environment CC Environment&#xff08;CC 环境&#xff09;主要用于创建 3D 环境映射&#xff0c;可以将一个 2D 图像转换为 3D 空间的反射或折射。该效果通常用于模拟真实世界的全景相机镜头和环境反射。 在实际操作中&#xff0c;可将效…

阿里云服务器带宽计费模式怎么选?有什么区别?

阿里云服务器公网带宽计费模式按固定带宽和按使用流量哪个划算&#xff1f;阿里云百科以北京地域为例&#xff0c;按固定带宽计费1M带宽一个月23元&#xff0c;按使用流量计费1GB流量0.8元&#xff0c;如果云服务器带宽使用率低于10%&#xff0c;那么首选按使用流量计费&#x…

中国省级、城市-数字经济创新创业、分项指数(2010-2020年)

一、数据介绍 数据名称&#xff1a;中国省级、城市-数字经济创新创业、分项指数 数据年份&#xff1a;2010-2020年 数据范围&#xff1a;31省、336个城市 数据来源&#xff1a;北大企业大数据研究中心 二、参考文献 参考文献&#xff1a; 戴若尘,王艾昭,陈斌开.中国数字…

【C++】模拟实现map和set(用红黑树进行封装)

模拟实现map和set 前言正式开始简单框架data的比较迭代器operatoroperator-\-[ ]重载 前言 本篇以前一篇红黑树模拟实现插入功能为基础&#xff1a;【C】红黑树模拟实现插入功能(包含旋转和变色) 本篇中不会再讲解关于旋转和变色的知识。只是对于红黑树进行简单的封装。 如果…

java操作mongdb【超详细】

Java操作 搭建 搭建 依赖 <!--mongodb--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>配置文件 spring:data:mongodb:host…

opencv图片换背景色

#include <iostream> #include<opencv2/opencv.hpp> //引入头文件using namespace cv; //命名空间 using namespace std;//opencv这个机器视觉库&#xff0c;它提供了很多功能&#xff0c;都是以函数的形式提供给我们 //我们只需要会调用函数即可in…

烧写PYNQ镜像到SD卡

一&#xff0c;安装 Win32diskimager 首先将Micro SD卡插入读卡器的卡槽中&#xff0c;然后再将读卡器插入计算机USB接口&#xff0c;此时计算机将会识别到插入的可移动磁盘。双击打开Win32DiskImager-1.0.0.zip 压缩文件&#xff0c;里面win32diskimager-1.0.0-install.exe文…

ORCA优化器浅析——CDXLOperator Base class for operators in a DXL tree

如上图所示&#xff0c;CDXLOperator作为Base class for operators in a DXL tree&#xff0c;其子类CDXLLogical、CDXLScalar、CDXLPhysical作为逻辑节点、物理节点和Scalar节点的DXL表示类&#xff0c;因此其包含了这些类的共同部分特性&#xff0c;比如获取其DXL节点表示的函…

CNN之图像识别

文章目录 1. 图像识别1.1 模式识别1.2 图像识别的过程1.3 图像识别的应用 2. 深度学习发展2.1 深度学习为何崛起2.2 分类与检测2.3 常见的卷积神经网络 3. VGG3.1 VGG163.2 VGG16的结构&#xff1a;3.3 使用卷积层代替全连接3.4 1*1卷积的作用3.5 VGG16代码示例 4. 残差模型-Re…

ctfshow-web8

0x00 前言 CTF 加解密合集CTF Web合集 0x01 题目 0x02 Write Up 这道题实际上就是一个单纯的布尔型盲注&#xff0c;只不过是过滤了一些东西&#xff0c;一个是过滤的空格&#xff0c;还有一个是过滤了逗号 那么我们需要做的就是对这两个进行绕过&#xff0c;空格还是用/**…

Spring系列五:手动实现Spring底层机制

文章目录 &#x1f35d;类加载器和classpath详解 &#x1f497;实现任务阶段1&#x1f35a;编写自己Spring容器, 扫描包得到bean的class对象 &#x1f497;实现任务阶段2&#x1f35a;扫描将bean信息封装到BeanDefinition对象, 并放入到Map &#x1f497;实现任务阶段3&#x1…

Unity 鼠标控制 UI 放大、缩小、拖拽

文章目录 1. 代码2. 测试场景 1. 代码 using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems;public class UIDragZoom : MonoBehaviour, IDragHandler, IScrollHandler {private Vector2 originalSize;private Vector2 originalPosition;private RectTr…

一个案例:Vue2组件化开发组件从入门到入土

1. 环境搭建 1.1. 创建项目 npm install -g vue/clivue create vue_study_todolist1.2. 清空项目代码 清楚HelloWorld.Vue代码中的内容。 1.3. 启动空项目 1.4 项目目标 项目组件实现以下效果 2. 组件拆分代码 Vue是一个基于组件的框架&#xff0c;允许您将界面拆分成小的…

【LeetCode】617.合并二叉树

题目 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xff0c;两棵树上的一些节点将会重叠&#xff08;而另一些不会&#xff09;。你需要将这两棵树合并成一棵新二叉树。合并的规则是&#xff1a;如果两个节点重叠…