Java面试题-Java核心基础-第十二天(SPI机制)

目录

一、什么是SPI机制

二、SPI机制的作用

三、SPI的一些应用

四、 例子


一、什么是SPI机制

SPI因为service provider interface 意为:服务提供者的接口

就是为服务提供者提供的接口,就是设计一套接口规范,然后不同的服务提供者去进行相应的实现

这个SPI机制依赖于Java库中的ServiceLoad类加载实现类才能实现这样一种机制

过程:

1. 需要提供一个接口

2. 服务提供者去实现接口,就有会对应的实现类

上面这样也能直接用,但是多个实现就有多个jar包,其实服务调用方和服务的提供者还是存在一定的耦合的,我想换一种,那里就要另外编写一种,存在耦合

ServiceLoad就可以加载出所有的实现类,得到实现类的集合。

说一下这个使用的步骤:

1.在接口的提供者这一方项目中的resource目录下面,创建好一个和接口全类名一模一样的文件,然后在这个文件中写好实现类的全类名

2. 然后就能使用ServiceLoad加载出文件中写的这些实现类,获取到这些实现类了,在接口的提供者实际上就能真正的使用自己写的实现类了,因为我仅仅实现接口有一个接口实现类是不行的,其实就是接口提供者这边其实是导入了那套接口规范,那套结构中其实是里面使用到了ServiceLoad去加载类的,然后再完成操作。其实实现类只是工具,具体怎样使用这个工具由定义接口规范的人说的,现在接口提供者这一方已经有了实现类了,有了接口规范了(其实并不是真正的是接口规范,而是说操作接口方法的一段代码逻辑)。现在的问题就是说到底怎样才能让真正的使用到这些实现类中的具体实现。当然不能直接new的方式,这样就写死了,就只能一种实现类。那有什么办法,就是说不通过new的方式,然后也能拿到实现类,并且这里是可以拿到所有的实现类对象,只有这样,才真正的解耦合。

其实:

接口规范这一边要干的活:

1. 定义接口  其实就是定义好接口中的方法  想清楚到底要一些什么样的方法,大致是想要干什么?

2. 定义操作接口方法的一套流程 通过这个流程就能真正的干活

服务提供者这一方需要干的活:

其实服务提供者的这一边它需要导入  这一套接口规范以及这一套方法流程 其实就是得到接口规范的这一方的全部  所以通常来说接口提供者这一方,需要导入接口规范的jar包

1. 写实现类

2. 项目中的resource目录下面,创建好一个和接口全类名一模一样的文件,然后在这个文件中写好实现类的全类名

只要这样  就可以通过ServiceLoad感知到这些实现类  将“实现类”填充到那个方法流程框架中

然后就能够真正的正常执行那一套流程了

因此我们现在只需要将服务提供者打一个jar包,然后我们调用方的这一边就导入这个jar包就能使用了  就能使用那套流程了   

二、SPI机制的作用

就是解耦合

它的强大之处在于我代码真的可以完完全全的写死,完完全全不需要任何的改动,就能直接使用到接口提供者给我们实现的方法

三、SPI的一些应用

jdbc 也是一个接口规范一方定义好一写接口 java.sql.Driver 写好这个里面的方法 

Connection connect(String url, java.util.Properties info)
throws SQLException;

java.sql.* 这个包下定义了接口  Connnct PrepareStatement ResultSet

然后不同的数据库厂商就根据这些接口写好对应的实现类

在之前还没有ServiceLoad这个类  所以它能做的就只能实现好那些接口  但是呢 其实还是不能直接用,那怎样才能用?那就需要服务调用 方完成加载驱动这一步的  只有完成了这一步相当于才真正的将实现类导入过来了 

现在有了ServiceLoad这个类,就可以调用它的load方法,然后就能自动的加载这个接口下面的实现类  所以现在数据库厂商那边就可以直接注册这个实现类了 通过规定的步骤  就是写一个文件

既然现在数据库厂商那边 相当于都把事情做好了,因此我们调用方这边就可以不需要再去完成注册驱动的这一步了,这一步可以省略了  这是JDBC4.0之后支持的

关键:

​
ServiceLoader<Driver> s = ServiceLoader.load(Driver.class);
ServiceLoader<Connection> s = ServiceLoader.load(Connection.class);
.....​

然后在数据库服务器厂商那边在项目的resouces目录下面写好:

一个 名为java.sql.Driver的文件 然后里面写Driver实现类的全类名

......

另外还有日志框架也是利用SPI机制

四、 例子

我们现在需要使用一个内容搜索接口,搜索的实现可能是基于文件系统的搜索,也可能是基于数据库的搜索。

  • 先定义好接口
  • public interface Search {public List<String> searchDoc(String keyword);   
    }

  • 文件搜索实现
  • public class FileSearch implements Search{@Overridepublic List<String> searchDoc(String keyword) {System.out.println("文件搜索 "+keyword);return null;}
    }
    

  • 数据库搜索实现
  • public class DatabaseSearch implements Search{@Overridepublic List<String> searchDoc(String keyword) {System.out.println("数据搜索 "+keyword);return null;}
    }
    

  • resources 接下来可以在resources下新建META-INF/services/目录,然后新建接口全限定名的文件:com.cainiao.ys.spi.learn.Search,里面加上我们需要用到的实现类
  • com.cainiao.ys.spi.learn.FileSearch

  • 测试方法
  • public class TestCase {public static void main(String[] args) {ServiceLoader<Search> s = ServiceLoader.load(Search.class);Iterator<Search> iterator = s.iterator();while (iterator.hasNext()) {Search search =  iterator.next();search.searchDoc("hello world");}}
    }
    

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

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

相关文章

防止消息丢失与消息重复——Kafka可靠性分析及优化实践

系列文章目录 上手第一关&#xff0c;手把手教你安装kafka与可视化工具kafka-eagle Kafka是什么&#xff0c;以及如何使用SpringBoot对接Kafka 架构必备能力——kafka的选型对比及应用场景 Kafka存取原理与实现分析&#xff0c;打破面试难关 防止消息丢失与消息重复——Kafka可…

Android 12.0 根据app包名授予app监听系统通知权限

1.概述 在12.0的系统rom产品定制化开发中,在一些产品核心开发中,第三方app需要开启系统通知权限,然后可以在app中,监听系统所有通知,来做个通知中心的功能,所以需要授权 获取系统通知的权限,然后来顺利的监听系统通知。来做系统通知的功能,首选分析下相关授权通知的功…

Netty实战-实现自己的通讯框架

通信框架功能设计 功能描述 通信框架承载了业务内部各模块之间的消息交互和服务调用&#xff0c;它的主要功能如下&#xff1a; 基于 Netty 的 NIO 通信框架&#xff0c;提供高性能的异步通信能力&#xff1b;提供消息的编解码框架&#xff0c;可以实现 POJO 的序列化和反序…

小程序 wxml2canvas开发文档

wxml: <view class"share__canvas share__canvas1"><view class"share__canvas1-text draw_canvas" data-type"text" data-text"这是一段无边距文字">这是一段无边距文字</view> </view> <canvas canvas-…

BurpSuite安装

下载 BurpSuite 下载 Java17 下载后确定版本 java -version获取启动器 密钥生成器 破解 将下载的 BurpSuite、启动器、密钥生成器&#xff0c;放入同一个目录 打开 CMD 进入该目录 启动密钥生成器 java -jar burp-keygen-scz.jar开启新的CMD&#xff0c;进入该目录 启动…

paddlepaddle使用实践过程中的问题记录

环境背景 python&#xff1a;3.10.11 系统&#xff1a;macOS Big Sur 11.7.10 cpu&#xff1a;Intel Core i7 2.6GHz 内存&#xff1a;16G paddle版本问题 初始安装的是的MacOS cpu 2.5.1版本&#xff0c;在python解释器中执行import paddle时报错&#xff1a; ImportError:…

SpringCache配置Redis有效解决缓存击穿和缓存雪崩问题

初始代码 作者参考的一篇CSDN的配置函数代码&#xff0c;实在不好意思&#xff0c;作者忘记是哪位博主了&#xff1a; /*** 设置CacheManager缓存规则* param factory* return*/Beanpublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializer<St…

Spring Boot - 启动主要流程

Spring Boot的启动主要流程可以概括为以下几个步骤&#xff1a; 加载Spring Boot配置&#xff1a; Spring Boot应用的启动从加载配置开始。Spring Boot会读取application.properties或application.yml等配置文件&#xff0c;将配置信息加载到Spring的Environment中&#xff0c;…

IOS屏幕旋转监听

IOS屏幕旋转 1.设计窗口,添加三个按钮 2.添加事件连接 3.按钮点击事件实现 先添加三个IBAction 实现IBAction 使用旋转立刻生效 -(IBAction)btnFixPortrait:(id)sender{//访问应用程序委托成员_app.mask UIInterfaceOrientationMaskPortrait;//设置窗口旋转属性[self setN…

企业安全—SDL概述篇

0x00 前言 众所周知&#xff0c;从源头开始就开发安全的代码&#xff0c;比产品已经成型之后付出的代价要小很多&#xff0c;也就是一直在说的安全左移的概念。最好就是从一开始&#xff0c;大家就用最安全的代码&#xff0c;或者是框架&#xff0c;那么开发出来的产品必然会减…

git rebase -i 详解

git rebase 命令简介 git rebase命令允许我们轻松地更改一系列提交&#xff0c;修改存储库的历史记录。我们可以重新排序、编辑或合并提交。一般常用git rebase来合并当前分支的多个commit记录&#xff08;压缩&#xff09;以及避免出现分支的交叉合并&#xff08;变基&#x…

ChatGPT课件汇总介绍

第二节:有效管理 Token,充分发挥 ChatGPT 的能力 OpenAI 官方计算token的测试地址:https://platform.openai.com/tokenizer 第三节:探索ChatGPT在不同领域的创新应用 1、小说撰写 1、我希望你能作为一个小说家。我会给你一个主题,请写出有创意的、吸引人的故事,能够长时…

MongoDB 学习笔记(基础)

概论 出现背景&#xff1a;MongoDB 是文档型数据库&#xff0c;由于传统的关系型数据库&#xff08;如 MySQL&#xff09;&#xff0c;在数据操作的“三高”需求以及应对 web 的网站需求面前显得有些吃力&#xff0c;在此环境下 MongoDB 出世了 三高需求&#xff1a; (1) 对数…

进程的优先级与LAMP项目部署实战

一、进程的优先级&#xff08;扩展&#xff09; 1、什么是进程的优先级 Linux是一个多用户、多任务的操作系统&#xff0c;系统中通常运行着非常多的进程。哪些进程先运行&#xff0c;哪些进程后运行&#xff0c;就由进程优先级来控制 思考&#xff1a;什么时候需要用到进程…

力扣-python-两数相加

题解 1: # Definition for singly-linked list. # class ListNode(object): # def __init__(self, val0, nextNone): # self.val val # self.next nextclass Solution(object):def addTwoNumbers(self, l1, l2):""":type l1: ListNode:t…

【MATLAB源码-第56期】基于WOA白鲸优化算法和PSO粒子群优化算法的三维路径规划对比。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1.粒子群算法&#xff08;Particle Swarm Optimization&#xff0c;简称PSO&#xff09;是一种模拟鸟群觅食行为的启发式优化方法。以下是其详细描述&#xff1a; 基本思想&#xff1a; 鸟群在寻找食物时&#xff0c;每只鸟都…

2023-10-17 LeetCode每日一题(倍数求和)

2023-10-17每日一题 一、题目编号 2652. 倍数求和二、题目链接 点击跳转到题目位置 三、题目描述 给你一个正整数 n &#xff0c;请你计算在 [1&#xff0c;n] 范围内能被 3、5、7 整除的所有整数之和。 返回一个整数&#xff0c;用于表示给定范围内所有满足约束条件的数…

华纳云:连接mysql出现2059错误怎么解决

MySQL连接错误2059通常表示MySQL服务器拒绝了连接。这种错误可能由多种原因引起&#xff0c;以下是一些可能的解决方法&#xff1a; 检查MySQL服务器是否正在运行&#xff1a; 确保MySQL服务器正在正常运行。您可以使用以下命令检查MySQL服务器的状态&#xff1a; systemctl st…

Object.prototype.toString.call() 和 instanceOf 和 Array.isArray() 详解

解析: 理解 Object.prototype.toString.call(), instanceof, 和 Array.isArray() 是 JavaScript 中重要的类型检查工具。以下是一个较为详细的解释和示例代码&#xff0c;帮助你理解它们的工作原理和使用场景 Object.prototype.toString.call()&#xff1a; Object.prototyp…

rust - 理解borrow trait

简介 borrow trait 是处理借用(即其它语言中的引用)的 trait,变量的所有权不会转移.泛型定义如下: pub trait Borrow<Borrowed: ?Sized> {/// Immutably borrows from an owned value.fn borrow(&self) -> &Borrowed; }其中包含一个 borrow(&self)的方…