java中SPI机制

news2025/2/21 21:11:43

一:作用

SPI的作用其实就是,在系统内部,定义一个能力接口,该接口可以满足自己的业务需要,比如发送短信,定义一个发送短信的接口,至于用什么方式实现,可以交给短信服务提供商去实现,然后根据自己的需要选择使用其中的实现放,这里需要注意几点。

1:x系统内部需要将所有的实现放的jar包都要依赖进来,因为实现类的代码是服务提供商写的

2: SPI就是一个选择的能力,选择使用哪个接口。

jia1需要开发一个接口,该接口的实现可以由jar2和jar3提供,所以在jar1中,一定要依赖jar2和jar3的依赖包。,才能使用SPI的能力。

该jar的依赖如下

+-jar1
  \-jar2
  \-jar3

二:如何使用


1. 服务接口定义:

// MyService.java
public interface MyService {
    void doSomething();
}


2. 服务提供者实现:

// MyServiceImpl1.java
public class MyServiceImpl1 implements MyService {
    @Override
    public void doSomething() {
        System.out.println("Implementation 1");
    }
}

// MyServiceImpl2.java
public class MyServiceImpl2 implements MyService {
    @Override
    public void doSomething() {
        System.out.println("Implementation 2");
    }
}


3. 服务提供者配置:


在类路径下的 META-INF/services/ 目录下创建以服务接口全限定名为名称的文件,文件内容为实现类的全限定名。

// 文件路径:META-INF/services/my.package.MyService
my.package.MyServiceImpl1
my.package.MyServiceImpl2

4. 服务加载

使用 ServiceLoader 类加载服务实现

// MyApplication.java
import java.util.ServiceLoader;

public class MyApplication {
    public static void main(String[] args) {
        ServiceLoader<MyService> serviceLoader = ServiceLoader.load(MyService.class);
        for (MyService service : serviceLoader) {
            service.doSomething();
        }
    }
}


5. 运行结果:

Implementation 1
Implementation 2

三:实战用法

1. 数据库驱动加载:

在 JDBC 中,数据库厂商提供的驱动就是通过 SPI 机制实现的。在类路径下的 META-INF/services/java.sql.Driver 文件中配置不同数据库厂商的驱动类。

2. 日志框架:

许多日志框架(如 SLF4J)使用 SPI 机制,允许用户在不修改代码的情况下切换不同的日志实现。

3. 插件系统:

SPI 也可以用于实现插件系统,使系统更加灵活,能够在运行时动态加载和卸载插件,扩展系统功能

四:实战用法举例

日志框架使用SPI机制来实现

4.1:引入SLF4J和日志框架的实现库

<!-- SLF4J API -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.32</version> <!-- 使用最新版本 -->
</dependency>

<!-- SLF4J 日志框架的实现,这里以Logback为例 -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version> <!-- 使用最新版本 -->
</dependency>

4.2:创建SLF4J的配置文件:

在类路径下的 resources 目录下创建 logback.xml 文件,用于配置Logback日志框架。具体配置根据你的需求来定义,以下是一个简单的例子

<!-- logback.xml -->
<configuration>
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="debug">
        <appender-ref ref="console"/>
    </root>
</configuration>

4.3:使用SLF4J API

在代码中使用SLF4J的API进行日志记录。SLF4J的API提供了Logger接口,通过这个接口进行日志记录。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyApp {
    private static final Logger logger = LoggerFactory.getLogger(MyApp.class);

    public static void main(String[] args) {
        logger.info("Hello, this is an info message.");
        logger.error("Oops, this is an error message.");
    }
}

4.4:SPI机制的作用

SPI机制的作用体现在选择日志框架实现的阶段。SLF4J通过SPI机制来查找和加载实际的日志框架的实现,无需在代码中硬编码指定实现类。这样,你可以在不修改代码的情况下切换不同的日志框架。

这个切换是通过在类路径下的 META-INF/services/org.slf4j.spi.SLF4JServiceProvider 文件中指定实际的日志框架提供者来实现的。在这个文件中,你可以指定使用Logback、Log4j、Java Util Logging等具体的实现。

# META-INF/services/org.slf4j.spi.SLF4JServiceProvider
ch.qos.logback.classic.util.ContextSelectorStaticBinder

在这个例子中,Logback的实现类被指定,SLF4J会在运行时通过SPI机制加载并使用Logback。

总体来说,使用SPI机制的日志框架,如SLF4J,允许你在不修改代码的情况下切换日志框架的实现,从而提高了代码的灵活性和可维护性

五:原理说明

  1. ServiceLoader 类: SPI 机制的入口是 ServiceLoader 类,它位于 java.util 包中。ServiceLoader 通过 ClassLoader 加载服务接口的实现。

  2. 查找服务文件: ServiceLoader 会根据服务接口的全限定名构建一个相对于类路径的文件路径,通常是 META-INF/services/ 下的文件。对于 java.sql.Driver 接口,路径是 META-INF/services/java.sql.Driver

  3. 读取服务文件内容: ServiceLoader 会读取该服务文件的内容,文件中的每一行都包含了一个服务提供者的实现类的全限定名。

  4. 加载服务提供者类: 对于每个实现类的全限定名,ServiceLoader 使用 ClassLoader 加载相应的类。

  5. 实例化服务提供者: 加载成功后,ServiceLoader 实例化这个服务提供者类的对象,并返回给调用方。

具体来说,当你调用 ServiceLoader.load(MyService.class) 时,ServiceLoader 会根据类路径找到 META-INF/services/my.package.MyService 文件,读取其中的实现类信息,然后使用 ClassLoader 加载这些实现类。最终,你就可以得到一个包含所有实现类对象的 ServiceLoader 实例,可以遍历这些对象并调用相关方法。

总体而言,SPI 机制的实现依赖于 Java 的类加载机制和类路径的概念,通过标准的文件配置和加载流程,实现了服务接口的动态发现和加载。

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

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

相关文章

[C/C++]数据结构 堆排序(详细图解)

一:前言 在[C/C]数据结构 堆的详解中,介绍了什么是堆,并且完成了堆的实现和一系列接口,包括向上调整法和向下调整法等,接下来小编介绍一个有点量级的排序方法------堆排序,时间复杂度为O(n*lgn) 二:堆排序详解 2.1 方法介绍 1.首先将待排序数组建为大堆,此时堆顶元素就为数组…

肖sir __数据库练习__001

建表语句&#xff1a; create table student ( id int(4),age int(8),sex int(4),name varchar(20), class int(4), math int(4)) DEFAULT charsetutf8; INSERT into student VALUES(1,25,1,‘zhansan’,1833,90); INSERT into student VALUES(2,25,1,‘lisi’,1833,67); INSER…

Windows安装Docker、自定义安装目录

目录 前言一、Docker安装包下载二、自定义Docker安装路径、设置到其他盘三、安装Docker四、安装后配置1.修改镜像保存路径2.自定义镜像源 五、Docker运行验证1.docker/welcome-to-docker2.MySQL服务 总结 前言 Docker是一种开源的容器化平台&#xff0c;可以让开发者使用容器的…

异步爬虫提速实践-在Scrapy中使用Aiohttp/Trio

在构建爬虫系统时&#xff0c;提高爬虫速度是一个关键问题。而使用异步爬虫技术可以显著提升爬取效率。在本文中&#xff0c;我将与大家分享如何在Scrapy中利用Aiohttp或Trio库实现异步爬取&#xff0c;以加快爬虫的速度。让我们开始吧&#xff01; 1. 安装所需的库 首先&…

MyBatis-Plus及多数据源入门教程

开发环境配置 JDK 1.8、Maven 3.8.8、 IDEA CE 2023.2、MySQL 8.0.34 框架介绍 MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。MyBatis 是一款非常优秀的开源…

企业级应用场景中,LLM 的数据特性剖析及处理对策

编者按&#xff1a;今年以来&#xff0c;大语言模型&#xff08;LLM&#xff09;在消费者(2C)市场崭露头角&#xff0c;同时也吸引了大量企业的关注。但是直接将这些面向消费者的模型引入企业环境&#xff0c;可能会面临一些风险。今天我们为大家带来的这篇文章&#xff0c;作者…

GPTs 初体验 - 1 分钟就能创建一个自己的 ChatGPT? | 京东云技术团队

就在 11.10 号早上&#xff0c;ChatGPT 已经偷摸的把GPTs功能&#xff0c;开放给所有尊贵的 Plus 用户了。 随着这波的功能开放&#xff0c;界面也是改了不少。点击左侧的 Explore 或者左下角的用户处&#xff0c;就可以直接进入新的 GPTs 功能&#xff1a; 这里可以看到我们…

Vue3挂载完毕后,隐藏dom再重新加载组件的方法

组件原本是在PC端使用的&#xff0c;现在需要把组件再封装一次&#xff0c;供app调用&#xff0c;但是在app上会显示tag栏&#xff0c;有占位影响空间&#xff0c;所以需求去掉头部tag&#xff0c;只显示下方组件。 实现方法&#xff0c;以前是直接引用的组件&#xff0c;现在改…

MySQL 前瞻

数据库 是一类软件&#xff0c;这一类软件可以用来“管理数据”&#xff08;对数据进行保存&#xff0c;增删改查 [与数据结构的有什么区别呢&#xff1f;]&#xff09; 数据结构是实现增删改查的具体方式 数据库则是管理数据的软件&#xff0c;实现数据库软件内部就用到了很…

2024重庆大学计算机考研分析

24计算机考研|上岸指南 重庆大学 重庆大学计算机考研招生学院是计算机学院和大数据与软件学院。目前均已出拟录取名单。 重庆大学计算机学院是我国高校最早开展计算机研究的基地之一&#xff0c;1978年和1986年获西南地区首个硕士和博士点&#xff0c;1998年成立计算机学院&a…

主机怎么通过命令行方式向虚拟机传输文件

这是几个月前遇到的问题了&#xff0c;那时候想着要记录下来&#xff0c;但后来忙忘了&#xff0c;这次想起来了&#xff0c;于是记录一下。 之前打靶场的时候需要将netcat-win32-1.12放入虚拟机的/var/www/html下&#xff0c;但是我虚拟机无法上网&#xff0c;也就是说无法直…

一篇搞懂Caffeine

概念 Caffeine是一个基于Java8开发的提供了近乎最佳命中率的高性能的缓存库。 缓存和ConcurrentMap有点相似&#xff0c;但还是有所区别。最根本的区别是ConcurrentMap将会持有所有加入到缓存当中的元素&#xff0c;直到它们被从缓存当中手动移除。但是&#xff0c;Caffeine的…

虹科Pico汽车示波器 | 汽车免拆检修 | 2016款东风悦达起亚K5车发动机怠速抖动严重、加速无力

一、故障现象 一辆2016款东风悦达起亚K5车&#xff0c;搭载G4FJ发动机&#xff0c;累计行驶里程约为8.2万km。该车发动机怠速抖动严重、加速无力&#xff0c;同时发动机故障灯异常点亮&#xff0c;为此在其他维修厂更换了所有点火线圈和火花塞&#xff0c;故障依旧&#xff0c;…

JavaScript 的 DOM 知识点有哪些?

文档对象模型&#xff08;Document Object Model&#xff0c;简称 DOM&#xff09;&#xff0c;是一种与平台和语言无关的模型&#xff0c;用来表示 HTML 或 XML 文档。文档对象模型中定义了文档的逻辑结构&#xff0c;以及程序访问和操作文档的方式。 当网页加载时&#xff0…

Linux 项目自动化构建工具:make/makefile

什么是 make make 是一个命令&#xff0c;他会在源文件的当前目录下寻找 makefile 或者 Makefile 文件执行这个文件中的代码。 makefile 文件的编写 我们先来见见猪跑&#xff0c;看看 make 怎么用的&#xff1a; 下面是 makefile 文件的内容&#xff1a; 这是 test.c 中的…

【AD9510 概要总结】A..

目录 特征FEATURES概述 GENERAL DESCRIPTION功能描述 FUNCTIONAL DESCRIPTIONPLL部分REFIN PLL参考输入—REFINVCO/VCXO时钟输入—CLK2PLL基准分频器—RVCO/VCXO 反馈分频器—N (P, A, B)A 和 B 计数器确定 P、A、B 和 R 的值 鉴频鉴相器&#xff08;PFD&#xff09;和电荷泵消…

国联易安:“主动防御”才能保障数据库安全

随着IT与互联网技术高速发展,政府、金融、电信、教育、医疗等各行业的数据成为了组织机构的核心资产。一旦数据被泄漏,不仅会造成严重经济损失&#xff0c;而且会带来极大负面社会影响。 国联易安国联数据库安全防护系统是一款基于数据库协议分析与控制技术的数据库主动防御系统…

如何编写自己的python包,并在本地进行使用

如何编写自己的python包,并在本地进行使用 一、直接引用 1.创建Python项目pythonProject。 2.并且在此项目下创建pg_message包。 3.pg_message包下默认生成_init_.py文件。 Python中_init_.py是package的标志。init.py 文件的一个主要作用是将文件夹变为一个Python模块,Pyt…

汇编程序:查0~9的平方表获得平方数

查平方表。在数据段中建立一个表格TABLE&#xff0c;存放0~9的平方值。从键盘输入一个十进制数字(0~9)&#xff0c;查表求键入数字的平方值。并把结果显示在CRT屏幕上。能够单步执行程序&#xff0c;认真观察、判断每条指令执行的结果是否正确&#xff0c;对错误结果&#xff0…

【网络安全】-常见的网站攻击方式详解

文章目录 介绍1. SQL 注入攻击攻击原理攻击目的防范措施 2. 跨站脚本攻击&#xff08;XSS&#xff09;攻击原理攻击目的防范措施 3. CSRF 攻击攻击原理攻击目的防范措施 4. 文件上传漏洞攻击原理攻击目的防范措施 5. 点击劫持攻击原理攻击目的防范措施 结论 介绍 在数字时代&a…