当前位置: 首页 > news >正文

[Java]SPI扩展功能

一、什么是SPI

Java SPI(Service Provider Interface)是Java官方提供的一种服务发现机制。
它允许在运行时动态地加载实现特定接口的类,而不需要在代码中显式地指定该类,从而实现解耦和灵活性。

二、实现原理

基于 Java 类加载机制和反射机制。

存在
开始
加载服务
ServiceLoader.load, 参数Class
检测META-INF/services文件夹
是否存在
接口全限定名命名
的文件
获取文件内
实现类的全限定名
反射创建
结束

三、优点

  • 松耦合性:具有很好的松耦合性,可以在运行时动态加载实现类,而无需在编译时将实现类硬编码到代码中。
  • 扩展性:可以为同一个接口定义多个实现类,使应用程序更容易扩展和适应变化。
  • 易于使用:只需要定义接口并指定实现类的类名,即可轻松地使用新的服务提供者。

四、使用

我的服务

新建接口

这个接口要给SPI实现者

package com.example.demo;
public interface Phone {void print();
}

使用

public static void main(String[] args) {ServiceLoader<Phone> phones = ServiceLoader.load(Phone.class);for (Phone phone:phones) {phone.print();}
}

这是时候我们还没有任何实现类。
所以ServiceLoader是加载不到的。
我们需要另一个服务去实现配置Phone接口,并引入另一个服务的依赖

其他的服务实现接口

另一个服务实现配置Phone接口

package com.example.demo2;public class HuaweiPhone implements Phone {@Overridepublic void print() {System.out.println("遥遥领先?");}
}

实现接口2

package com.example.demo2;
public class XiaomiPhone implements Phone{@Overridepublic void print() {System.out.println("Are you ok?");}
}

在META-INF/services创建配置

创建com.example.demo.Phone的文件
内容:

com.example.demo2.HuaweiPhone
com.example.demo2.XiaomiPhone

相关文章:

[Java]SPI扩展功能

一、什么是SPI Java SPI&#xff08;Service Provider Interface&#xff09;是Java官方提供的一种服务发现机制。 它允许在运行时动态地加载实现特定接口的类&#xff0c;而不需要在代码中显式地指定该类&#xff0c;从而实现解耦和灵活性。 二、实现原理 基于 Java 类加载…...

机器人命令表设计

演算命令 CLEAR 将数据 1 上被指定的编号以后的变数的内容&#xff0c;以及数据 2 上仅被指定的个数都清除至 0。 INC 在被指定的变数内容上加上 1。 DEC 在被指定的变数内容上减掉 1。 SET 在数据 1 上设定数据 2。 ADD 将数据 1 和数据 2 相加&#xff0c;得出的结果保存在数…...

STM32--WDG看门狗

文章目录 WDG简介IWDGIWDG的超时计算WWDGWWDG超时和窗口值设定独立看门狗工程WWDG工程 WDG简介 WDG看门狗&#xff08;Watchdog Timer&#xff09;是一种常见的硬件设备&#xff0c;在STM32F10系列中&#xff0c;有两种看门狗&#xff0c;分别是独立看门狗和窗口看门狗&#x…...

(※)力扣刷题-字符串-实现 strStr()(KMP算法)

28 实现 strStr() 实现 strStr() 函数。 给定一个 haystack 字符串和一个 needle 字符串&#xff0c;在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在&#xff0c;则返回 -1。 示例 1: 输入: haystack “hello”, needle “ll” 输出: 2 示例…...

Redis 集群 Redis 事务 Redis 流水线 Redis 发布订阅 Redis Lua脚本操作

Redis 集群 & Redis 事务 & Redis 流水线 & Redis 发布订阅 Redis 集群linux安装redis主从配置查看当前实例主从信息 Redis Sentinelsentinel Redis Cluster Redis 事务Redis 流水线Redis 发布订阅Redis Lua脚本操作 Redis 集群 linux安装redis 下载安装包&#…...

【算法与数据结构】--常见数据结构--栈和队列

一、栈 栈&#xff08;Stack&#xff09; 是一种基本的数据结构&#xff0c;具有后进先出&#xff08;LIFO&#xff09;的特性&#xff0c;类似于现实生活中的一叠盘子。栈用于存储一组元素&#xff0c;但只允许在栈顶进行插入&#xff08;入栈&#xff09;和删除&#xff08;…...

Linux shell编程学习笔记11:关系运算

Linux Shell 脚本编程和其他编程语言一样&#xff0c;支持算数、关系、布尔、字符串、文件测试等多种运算。前面几节我们研究了 Linux shell编程 中的 字符串运算 和 算术运算&#xff0c;今天我们来研究 Linux shell编程中的的关系运算。 一、关系运算符功能说明 运算符说明…...

JS标准库

学习一门编程语言不仅是掌握其语法。同等重要的是学习其标准库&#xff0c;从而熟练掌握语言本身提供的所有工具。 1 定型数组 js常规数组与C和Java等较低级语言的数组类型还是有很大区别。ES6新增了定型数组&#xff0c;与这些语言的低级数组非常接近。 定型数组严格来说并…...

Android 12.0 hal层添加自定义hal模块功能实现

1. 前言 在12.0的系统rom定制化开发中,在 对hal模块进行开发时,需要通过添加自定义的hal模块来实现某些功能时,就需要添加hal模块的相关功能,接下来就来实现一个案例来供参考 接下来就来具体实现这个功能 2.hal层添加自定义hal模块功能实现的核心类 hardware\interfaces…...

如何理解vue声明式渲染

Vue.js中的声明式渲染是一种用来描述用户界面的方式&#xff0c;它强调“声明”应该如何渲染页面&#xff0c;而不需要关心底层的DOM操作。这与传统的命令式渲染方式&#xff0c;即手动控制DOM元素的创建、更新和销毁&#xff0c;形成了鲜明的对比。 理解Vue的声明式渲染的关键…...

【已解决】Vue全局引入scss 个别页面不生效 / 不自动引入全局样式

项目里配置了全局样式的引入&#xff0c;今天新建了 demo 页面去修改 element 的样式&#xff0c;发现全局的样式没有引入进来。 问题原因 在此页面 没有任何样式导致的 项目在编译的时候&#xff0c;会把 .vue 文件的样式抽离到单独的 css 文件中。 当该页面没有css代码的时…...

MySQL之双主双从读写分离

一个主机 Master1 用于处理所有写请求&#xff0c;它的从机 Slave1 和另一台主机 Master2 还有它的从 机 Slave2 负责所有读请求。当 Master1 主机宕机后&#xff0c; Master2 主机负责写请求&#xff0c; Master1 、 Master2 互为备机。架构图如下 : 准备 我们…...

使用eBPF加速阿里云服务网格ASM

背景 随着云原生应用架构的快速发展&#xff0c;微服务架构已经成为了构建现代应用的主要方式之一。而在微服务架构中&#xff0c;服务间的通信变得至关重要。为了实现弹性和可伸缩性&#xff0c;许多组织开始采用服务网格技术来管理服务之间的通信。 Istio作为目前最受欢迎的…...

大型数据集处理之道:深入了解Hadoop及MapReduce原理

在大数据时代&#xff0c;处理海量数据是一项巨大挑战。而Hadoop作为一个开源的分布式计算框架&#xff0c;以其强大的处理能力和可靠性而备受推崇。本文将介绍Hadoop及MapReduce原理&#xff0c;帮助您全面了解大型数据集处理的核心技术。 Hadoop简介 Hadoop是一个基于Google…...

LCR 095. 最长公共子序列(C语言+动态规划)

1. 题目 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符&#xff08…...

程序员不写注释:探讨与反思

一、为什么程序员不写注释 当程序员选择不写注释时&#xff0c;通常有一系列常见原因&#xff0c;这些原因可以影响他们的决策和行为。同时&#xff0c;这个决策可能会带来多方面的影响和后果。以下是详细阐述为什么程序员不写注释的常见原因以及这种决策可能导致的影响和后果…...

《论文阅读:Dataset Condensation with Distribution Matching》

点进去这篇文章的开源地址&#xff0c;才发现这篇文章和DC DSA居然是一个作者&#xff0c;数据浓缩写了三篇论文&#xff0c;第一篇梯度匹配&#xff0c;第二篇数据增强后梯度匹配&#xff0c;第三篇匹配数据分布。DC是匹配浓缩数据和原始数据训练一次后的梯度差&#xff0c;DS…...

免费chatGPT工具

发现很多人还是找不到好用的chatGPT工具&#xff0c;这里分享一个邮箱注册即可免费试用。 PromptsZone - 一体化人工智能平台使用 PromptsZone 与 ChatGPT、Claude、AI21 Labs、Google Bard 聊天&#xff0c;并使用 DALL-E、Stable Diffusion 和 Google Imagegen 创建图像&…...

数据分析基础:数据可视化+数据分析报告

数据分析是指通过对大量数据进行收集、整理、处理和分析&#xff0c;以发现其中的模式、趋势和关联&#xff0c;并从中提取有价值的信息和知识。 数据可视化和数据分析报告是数据分析过程中非常重要的两个环节&#xff0c;它们帮助将数据转化为易于理解和传达的形式&#xff0…...

settings.xml的文件配置大全

settings.xml 文件中最常配置的还是这几个标签 localRepository和mirrors settings.xml文件官方文档地址 <settings xmlns"http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"ht…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...