Java中SPI机制原理解析

news2024/11/15 3:58:07

使用SPI机制前后的代码变化

  • 加载MySQL对JDBC的Driver接口实现
    在未使用SPI机制之前,使用JDBC操作数据库的时候,一般会写如下的代码:
    // 通过这行代码手动加载MySql对Driver接口的实现类
    Class.forName("com.mysql.jdbc.Driver")
    DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/study", "root", "root");
    
    在使用了SPI机制之后,就直接可以调用DriverManager.getConnection()方法获取连接了。
  • SLF4J查找日志门面实现
    在未使用SPI机制之前,SLF4J日志门面在查找具体的日志实现时,需要每个实现提供一个叫org.slf4j.com.impl.StaticLoggerBinder.class类,这里其实就跟SPI机制有点类似了,这个类实现了和SPI机制中的配置文件的功能,通过这个类来实现和具体实现的绑定关系。
    20240721170318
    使用了SPI机制之后则是通过SLF4JServiceProvider类来实现和具体实现的绑定关系。
    20240721171037
    20240721174312

SPI代码实现案例

假设现在有一个Plugin的接口,调用方通过PluginFactory中的installPlugins方法来加载实现实现类,并进行调用,代码如下所示:

// Plugin接口
public interface Plugin {
    boolean install(Map<Object, Object> context);
}

public class PluginFactory {
    public void installPlugins() {
        Map<Object, Object> context = new HashMap<>();
        context.put("_beans", new ArrayList<>());
        context.put("_version", "1.0.0");
        context.put("_aspects", new HashMap<>());

        // 这里通过ServiceLoader加载Plugin的实现类
        ServiceLoader<Plugin> loader = ServiceLoader.load(Plugin.class);
        for (Plugin plugin : loader) {
            plugin.install(context);
        }
    }

    public static void main(String[] args) {
        PluginFactory factory = new PluginFactory();
        factory.installPlugins();
    }
}

Plugin接口实现者的代码:

public class LogPlugin implements Plugin {
    private static final Logger LOGGER = LogManager.getLogger();

    @Override
    public boolean install(Map<Object, Object> context) {
        LOGGER.info("Login plugin is initiating...");
        return true;
    }
}

20240721214035
20240721214130

使用SPI机制有个好处就是:当需要切换不同的实现类时,无需对业务代码进行适配修改,直接将Maven配置里面的实现依赖切换即可,对于实际的环境可能就是直接将对应的jar包替换到对应的lib目录下,然后重启服务即可。

SPI代码实现原理

ServiceLoader的load方法实现原理是通过接口的全限定名称去读取META-INF/services路径下的文件,获取文件里面实现类的全限定名,然后加载该类,并通过反射的方式调用构造器获取实现类的实例,然后返回,如下图所示:
20240721215047

20240721214737

20240721215650

20240721214937

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

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

相关文章

鸿蒙开发error: failed to start ability

鸿蒙开发项目编译过后不能启动 项目在模拟器运行报&#xff1a; error: failed to start ability. Error while Launching ability 解决办法&#xff1a; 1&#xff0c;看了一些文章说是把module.json5配置文件中的"exported"由false改成true&#xff0c;没有解…

Python 实现股票指标计算——BIAS

BIAS (Bias Ratio) - 乖离率 1 公式 BIAS (当日收盘价 - N日平均收盘价) ➗ N日平均收盘价 ✖ 100&#xff05; N一般取6、12、24 2 数据准备 我们以科创50指数 000688 为例&#xff0c;指数开始日期为2019-12-31&#xff0c;数据格式如下&#xff1a; 3 计算过程 def c…

Java 中的异常

异常&#xff1a;就是出现的问题。 在Java中异常被当成对象进行处理&#xff0c;所有的异常类都继承于Throwable类&#xff0c;如果Java提供的异常类并不能满足需求&#xff0c;用户还可以自己定义一个异常类。 下面是异常体系结构&#xff1a; Throwable又分成了Error和Exce…

《无所不能的JavaScript · 对象简介》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

OpenStack Yoga版安装笔记(七)glance练习补充

1、练习场景说明 在OpenStack Yoga版安装笔记&#xff08;五&#xff09;中&#xff0c;glance已经在controller node虚拟机上安装完成&#xff0c;并且已经成功拍摄了快照。 此时&#xff0c;controller node虚机已经安装了keystone、keystone DB、glance、glance DB、OpenSta…

利用【MATLAB】和【Python】进行【图与网络模型】的高级应用与分析】

目录 一、图与网络的基本概念 1. 无向图与有向图 2. 简单图、完全图、赋权图 3. 顶点的度 4. 子图与连通性 5. 图的矩阵表示 MATLAB代码实例 Python代码实例 二、最短路径问题 1. 最短路径问题的定义 2. Dijkstra算法 MATLAB代码实例 Python代码实例 三、最小生…

昇思MindSpore学习总结十七 —— 基于MindSpore通过GPT实现情感分类

1、要求 2、导入了一些必要的库和模块 以便在使用MindSpore和MindNLP进行深度学习任务时能使用各种功能&#xff0c;比如数据集处理、模型训练、评估和回调功能。 import os # 导入操作系统相关功能的模块&#xff0c;如文件和目录操作import mindspore # 导入MindSpore库&a…

入门C语言只需一个星期(星期六)

点击上方"蓝字"关注我们 01、创建结构体 struct MyStructure { // 结构声明 int myNum; // 成员&#xff08;int 变量&#xff09; char myLetter; // 成员&#xff08;char 变量&#xff09;}; // 用分号结束结构创建一个名为 s1 的结构变量​struct myStru…

# Redis 入门到精通(九)-- 主从复制(1)

Redis 入门到精通&#xff08;九&#xff09;-- 主从复制&#xff08;1&#xff09; 一、redis 主从复制 – 主从复制简介 1、互联网“三高”架构 高并发高性能高可用 2、你的“Redis”是否高可用&#xff1f; 1&#xff09;单机 redis 的风险与问题 问题1.机器故障  现…

kafka服务介绍

kafka 安装使用管理 Kafka Apache Kafka 是一个开源的分布式事件流平台&#xff0c;主要用于实时数据传输和流处理。它最初由 LinkedIn 开发&#xff0c;并在 2011 年成为 Apache 基金会的顶级项目。Kafka 设计的目标是处理大规模的数据流&#xff0c;同时提供高吞吐量、低延迟…

C语言 通讯录管理 完整代码

这份代码&#xff0c;是我从网上找的。目前是能运行。我正在读。有些不懂的地方&#xff0c;等下再记录下来。 有些地方的命名&#xff0c;还需要重新写一下。 比如: PersonInfo* info &address_book->all_address[address_book->size]; 应该改为&#xff1a; Perso…

C#实现数据采集系统-实现功能介绍

系统介绍 我们这里主要使用C#( .Net 6)来实现一个数据采集系统&#xff0c;从0到1搭建数据采集系统&#xff0c;从系统分析&#xff0c;功能拆解&#xff0c;到一一实现 数据采集 数据采集是企业信息化和数字化转型过程中的关键环节&#xff0c;它涉及到从生产设备、传感器…

Microsoft Visual C++ 2010 Express 使用

Microsoft Visual C 2010 Express 使用 Microsoft Visual C 2010 Express&#xff08;简称VC 2010 Express&#xff09;是一款免费的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为C和C语言的开发者设计。 安装 下载|本站链接【VC2010简体中文版】的安装包并解压…

2024年新手卖家该如何做好亚马逊运营?

随着电子商务的蓬勃发展&#xff0c;越来越多的新手卖家选择在亚马逊这一国际电商巨头平台上开展业务。然而&#xff0c;想要在竞争激烈的市场中脱颖而出&#xff0c;新手卖家需要精心规划并执行有效的运营策略。以下是为2024年新手卖家提供的关于如何做好亚马逊运营的一些建议…

C#学习-刘铁猛

文章目录 1.委托委托的具体使用-魔板方法回调方法【好莱坞方法】&#xff1a;通过委托类型的参数&#xff0c;传入主调方法的被调用方法&#xff0c;主调方法可以根据自己的逻辑决定调用这个方法还是不调用这个方法。【演员只用接听电话&#xff0c;如果通过&#xff0c;导演会…

刷题笔记 739. 每日温度 (单调栈),215. 数组中的第K个最大元素(堆),347.前 K 个高频元素

739. 每日温度 &#xff08;单调栈&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/daily-temperatures/description/?envTypestudy-plan-v2&envI…

Fast Planner规划算法(一)—— Fast Planner前端

本系列文章用于回顾学习记录Fast-Planner规划算法的相关内容&#xff0c;【本系列博客写于2023年9月&#xff0c;共包含四篇文章&#xff0c;现在进行补发第一篇&#xff0c;其余几篇文章将在近期补发】 一、Fast Planner前端 Fast Planner的轨迹规划部分一共分为三个模块&…

Haproxy服务

目录 一.haproxy介绍 1.主要特点和功能 2.haproxy 调度算法 3.haproxy 与nginx 和lvs的区别 二.安装 haproxy 服务 1. yum安装 2.第三方rpm 安装 3.编译安装haproxy 三.配置文件详解 1.官方地址配置文件官方帮助文档 2.HAProxy 的配置文件haproxy.cfg由两大部分组成&…

React+TypeScript 组件库开发全攻略:集成Storybook可视化与Jest测试,一键发布至npm

平时我除了业务需求&#xff0c;偶尔会投入到UI组件的开发中&#xff0c;大多数时候只会负责自己业务场景相关或者一小部分公共组件&#xff0c;极少有从创建项目、集成可视化、测试到发布的整个过程的操作&#xff0c;这篇文章就是记录组件开发全流程&#xff0c;UI组件在此仅…

RabbitMQ学习实践二:MQ的实现

文章是本人在学习springboot实现消息队列功能时所经历的过程的记录&#xff0c;仅供参考&#xff0c;如有侵权请随时指出。 参考文章地址&#xff1a; RabbitMQ安装与入门_rabbitmq win11配置-CSDN博客 RabbitMQ入门到实战一篇文章就够了-CSDN博客 RabbitMQ系列&#xff08…