Java SPI 概念和应用实现

news2024/9/27 19:25:57

Java SPI 测试 Demo

  • 一.SPI 简介
    • 1.概念 SPI 与 API
    • 2.作用
  • 二.Jdk SPI 实现
    • 1.SPI 接口定义
    • 2.SPI 实现类定义
    • 3.SPI 配置
    • 4.测试
  • 三.SpringBoot SPI 实现
    • 1.引入 SpringBoot 依赖
    • 2.SpringBoot SPI 配置
    • 3.测试

一.SPI 简介

1.概念 SPI 与 API

SPI 全称:Service Provider Interface (服务提供接口)

API 全称:Application Programming Interface (应用程序接口)

SPI 多用于框架扩展点,在底层代码中应用较多;在 Java 中,JDK 有一套内置的 SPI 程序扩展点,
Java 中 SPI 的使用场景有 Dubbo 、Spring、Logger、JDBC 等;
虽然业务代码中很少使用 SPI ,但是个人认为 SPI 和业务代码中定义的接口与实现,在思想上更一致

而 API 其实就是程序接口,供 UI 或第三方调用的,与 SPI 有着本质区别 

2.作用

在应用框架中,作为一组顶层接口,用于为可扩展组件的供应商提供统一接口;方便通过配置指定不同供应商的实现。
以 JDBC 为例,可以利用 SPI 机制方便切换同一数据库的不同驱动实现,或切换不同库的驱动

二.Jdk SPI 实现

1.SPI 接口定义

定义一个动物接口,用于不同动物供应商去实现

package org.example.demo.spi.inter;

/**
 * @author moon
 * @date 2023-02-15 22:59
 * @since 1.8
 */
public interface AnimalSpi {

    /**
     * 喂养
     */
    void feed();
}

2.SPI 实现类定义

猫的实现

package org.example.demo.spi;

import org.example.demo.spi.inter.AnimalSpi;

/**
 * @author moon
 * @date 2023-02-15 23:03
 * @since 1.8
 */
public class Cat implements AnimalSpi {

    @Override
    public void feed() {
        System.out.println("Cats eat fish.");
    }
}

狗的实现

package org.example.demo.spi;

import org.example.demo.spi.inter.AnimalSpi;

/**
 * @author moon
 * @date 2023-02-15 23:02
 * @since 1.8
 */
public class Dog implements AnimalSpi {

    /**
     * 狗吃肉
     */
    @Override
    public void feed() {
        System.out.println("Dogs eat meat.");
    }
}

3.SPI 配置

在这里插入图片描述
在这里插入图片描述

1.SPI 配置文件位置:资源目录下,新建 META-INF 目录,再创建 services 目录
2.SPI 配置文件命名:SPI 接口的全限定名,多个 SPI 接口则创建多个文件,如 org.example.demo.spi.inter.AnimalSpi
3.SPI 配置文件内容:SPI 实现类的全限定名,多个实现则写多行,如 org.example.demo.spi.Dog

4.测试

package org.example.demo;

import org.example.demo.spi.inter.AnimalSpi;

import java.util.ServiceLoader;

/**
 * @author moon
 * @date 2023-02-15 23:05
 * @since 1.8
 */
public class AppSpi {

    public static void main(String[] args) {
        ServiceLoader<AnimalSpi> loader = ServiceLoader.load(AnimalSpi.class);
        loader.forEach(k->{
            k.feed();
        });
    }
}

结果

在这里插入图片描述

三.SpringBoot SPI 实现

1.引入 SpringBoot 依赖

上面 Jdk 的 SPI 测试时,未引入额外依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>DynamicDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>19</maven.compiler.source>
        <maven.compiler.target>19</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.7.2</version>
        </dependency>
    </dependencies>

</project>

2.SpringBoot SPI 配置

在这里插入图片描述
在这里插入图片描述

不同于 JDK 的 SPI 
SpringBoot 自己实现的 SPI 配置如下
1.SPI 配置文件位置:资源目录下,新建 META-INF 目录
2.SPI 配置文件命名:固定文件名称 spring.factories
3.SPI 配置文件内容:SPI 接口的全限定名,多个接口写多行,每行多个实现用 【,】拼接,如 org.example.demo.spi.Dog,org.example.demo.spi.Cat

多个接口和实现配置如图:
在这里插入图片描述

3.测试

package org.example.demo;

import org.example.demo.spi.inter.AnimalSpi;
import org.springframework.core.io.support.SpringFactoriesLoader;

import java.util.List;

/**
 * @author moon
 * @date 2023-02-15 23:05
 * @since 1.8
 */
public class AppSpi {

    public static void main(String[] args) {
        List<AnimalSpi> spi = SpringFactoriesLoader.loadFactories(AnimalSpi.class,Thread.currentThread().getContextClassLoader());
        spi.forEach(k->{
            k.feed();
        });
    }
}

结果

在这里插入图片描述

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

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

相关文章

Xshell连接阿里云服务器搭建网站

一、建设一个网站的基本要求 申请一个独立的域名申请一台云服务器ECS在服务器上安装网站环境&#xff0c;如&#xff1a;Apache发布网站内容至云服务器将第一步注册的域解析至云服务器的外网IP地址进行ICP备案 二、用户访问网站的过程 在浏览器上输入域名浏览器自动调用DNS&…

SPI(服务提供发现机制)简单使用

一、概述 SPI的英文全称是Service Provider Interface&#xff0c;是Java内置的一种服务提供发现机制。一般常用于一些框架或组件库的开发&#xff0c;我们最熟悉JDBC就应用到了SPI机制&#xff0c;并且在Spring、Dubbo中也大量应用了SPI机制。SPI机制是针对同一个接口采用不同…

质量小议18 -- 熵

未能深入理解其包含的物理意义&#xff0c;浅记于此&#xff0c;以求理解对抗有自然无序的过程。 熵&#xff0c;对系统无序程序的度量&#xff0c;表征系统混乱程度。系统总是由有序向无序&#xff0c;最后走向静寂。 关键词&#xff1a;1. 无序和混乱&#xff1b;2. 有序向无…

Java中static关键字和代码块的学习

本文介绍了Java中static关键字的使用,即静态成员变量和成员方法以及使用,静态与非静态成员变量和方法的对比总结 Java中的代码块介绍与最后结合代码块和构造方法后的初始化代码执行顺序的练习 static和代码块的学习三.认识static关键字1.static修饰成员变量2.static修饰成员方法…

GAMES101-计算机图形学入门 LEC4: TRANSFORMATION-3D

本节课程视频地址&#xff1a;https://www.bilibili.com/video/BV1X7411F744/?p4 补充上一节课的一个内容&#xff0c;旋转矩阵的逆矩阵是它的转置&#xff0c;也就是说有R−θRθ−1RθTR_{-\theta} R_\theta^{-1}R_\theta^TR−θ​Rθ−1​RθT​ 上节课讲了&#xff0c;…

【go】结合一个go开源项目分析谷歌浏览器cookie为什么不安全 附go项目导包失败怎么解决教程

本文创作背景 源于谷歌浏览器提示密码被泄露 并且某站很快收到了异地企图登录的提醒。 当即怀疑是不是谷歌浏览器保存的密码不安全&#xff0c;最后查阅诸多资料 并找到一个go语言编写的开源项目进行研究&#xff0c;虽然最终不能确定密码是如何泄露的 但研究结论还是让人不由感…

在华为MateBook Ego的arm windows 11上安装hyper-V虚拟机

入手一台华为matebook Ego的笔记本&#xff0c;由于想要测试一些arm的驱动功能&#xff0c;经常会把系统搞蓝屏&#xff0c;于是想安装一个虚拟机&#xff0c;于是试了vmware ,visual-box&#xff0c;由于本机是arm架构上面两个软件都无法进行正常安装&#xff0c;可能是由于有…

Excel+SQL实战项目 - 餐饮业日销售情况分析仪

目录1、要完成的任务2、认识数据3、SQL数据加工4、excel形成分析仪1、要完成的任务 目标&#xff1a;结合SQL和excel实现餐饮业日销售情况分析仪&#xff0c;如下表&#xff1a; 认识分析仪&#xff1a; 切片器&#xff1a;店面 分为四部分&#xff1a;KPI 、组合图、饼图、数…

如何自学芯片设计?

众所周知&#xff0c;芯片设计自学还是比较困难的&#xff0c;更不存在速成的。这里简单说一下学习的规划。 学会相应的知识 无论是科班毕业&#xff0c;还是理工科专业&#xff0c;想要入行IC&#xff0c;那就一定要具备相关的基础知识。尤其是在学校里&#xff0c;学习的很…

Centos7 内核升级

一、背景 在 CentOS 使用过程中&#xff0c;高版本的应用环境可能需要更高版本的内核才能支持&#xff0c;所以难免需要升级内核&#xff0c;所以下面将介绍yum和rpm两种升级内核方式。 关于内核种类: kernel-ml——kernel-ml 中的ml是英文【 mainline stable 】的缩写&…

2W字正则表达式基础知识总结,这一篇就够了!!(含前端常用案例,建议收藏)

正则表达式 (Regular Expression&#xff0c;简称 RE 或 regexp ) 是一种文本模式&#xff0c;包括普通字符&#xff08;例如&#xff0c;a 到 z 之间的字母&#xff09;和特殊字符&#xff08;称为"元字符"&#xff09;正则表达式使用单个字符串来描述、匹配一系列匹…

wpscan常见的使用方法

目录 简单介绍 暴力破解 信息收集 指定用户爆破 命令集合 简单介绍 Wordpress是一个以PHP和MySQL为平台的免费自由开源的博客软件和内容管理系统。 WPScan是Kali Linux默认自带的一款漏洞扫描工具&#xff0c;它采用Ruby编写&#xff0c;能够扫描WordPress网站中的多种安…

微信微店怎么开店铺步骤【微信开店】

商家在微信平台主要是通过什么方式进行卖货呢&#xff0c;大家的答案都会是微信小店、小程序微店铺之类的&#xff0c;的确微信店铺是商家在微信平台上重要的卖货渠道&#xff0c;那么微信微店怎么开店铺&#xff0c;下面就给大家分享微信微店怎么开店铺步骤。 一、准备好资料…

Netty启动流程源码剖析

案例 本文利用natty-all-source 包下的的demo案例 echo来分析下源码&#xff0c;代码如下&#xff1a;server 端代码 /*** Echoes back any received data from a client.*/ public final class EchoServer {static final boolean SSL System.getProperty("ssl") …

day14_oop_抽象_接口

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、作业 二、抽象 三、接口 零、 复习昨日 多态的好处: 扩展性强.加入新的功能,不需要改动代码降低代码耦合度(解耦合或者松耦合) 一、抽象类 1.1 抽象类…

C# VS2010 Winform 学习笔记遇见问题

参考书本《Visual C# .Net程序设计与应用开发》 学习C#&#xff1a; 对象的封装性&#xff1a;通过get()、set()函数读写。 1.Visual C#面向对象编程中的继承、多态。 2.enum&#xff1a;枚举&#xff0c;array.copy方法&#xff1a;数组拷贝&#xff0c;public static voi…

以应用为导向,看声纹识别中的音频伪造问题

声纹识别&#xff0c;又称说话人识别&#xff0c;是根据语音信号中的声纹特征来识别话者身份的过程&#xff0c;也是一种重要的生物认证手段。历经几十年的研究&#xff0c;当前声纹识别系统已取得了令人满意的性能表现&#xff0c;并在安防、司法、金融、家居等诸多领域中完成…

jenkins构建报错:.java:16: error: package javafx.util does not exist

1、报错 jenkins构建报错 package javafx.util does not exist2、报错原因 代码发现使用了javafx类&#xff0c;该类仅存在OracleJDK中&#xff0c;OpenJDK中没有该类。 jenkins服务器安装的是openjdk 3、卸载OpenJDK 具体不概述了 4、离线安装OracleJDK 1&#xff09;…

SPI规范的使用和简介

前言 SPI全称Service Provider Interface&#xff0c;是Java提供的一套用来被第三方实现或者扩展的API&#xff0c;它可以用来启用框架扩展和替换组件。 整体机制图如下&#xff1a; Java SPI 实际上是“基于接口的编程&#xff0b;策略模式&#xff0b;配置文件”组合实现的…

win11/10+opencv3.x/4.x配置 VS2019方法(简单使用,亲测)

首先下载 opencv&#xff0c;去官网下载百度》输入opencv&#xff0c;点击opencv|home&#xff0c;进入官网。点击 “Library”---->Release点击 对应版本下的 window版本&#xff0c;点击 --安装--extract---》设置路径。这个就是把库文件扩展到指定的路径下&#xff0c;扩…