Java中SPI机制原理解析

news/2024/12/25 20:50:39/文章来源:https://www.cnblogs.com/javadaydayup/p/18631387

使用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();@Overridepublic 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.hqwc.cn/news/858825.html

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

相关文章

Transformers 框架 Pipeline 任务详解(六):填充蒙版(fill-mask)

本文介绍了Hugging Face Transformers框架中的fill-mask任务,涵盖其作用、应用场景如机器翻译和文本补全,以及配置方法。通过Python代码示例展示了如何使用预训练模型自动下载或本地加载来创建Pipeline并执行填空任务。此外,还提供了利用Gradio构建WebUI界面的指南,使用户能…

阿里发布多模态推理模型 QVQ-72B,视觉、语言能力双提升;OpenAI 正在研发人形机器人丨 RTE 开发者日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文章 」、「有看点的 会议 」,但内容仅代表编辑…

python多进程,通过内存共享来通信,使用进程锁来防止数据问题

代码:import multiprocessing import time 使用锁和multiprocessing.Value,multiprocessing.Array,multiprocessing.Manager().listdef worker1(shared_number1, lock):for _ in range(10):with lock:shared_number1.value += 1def worker2(shared_array1, lock):for i in…

Jenkins入门使用

Jenkins入门使用 1先安装jdk才能运行jenkins yum install -y java-1.8.0-openjdk.x86_642 安装jenkins,运行,进行端口绑定,启动jenkins docker search jenkins docker pull jenkins/jenkins docker run -d -u root -p 8080:8080 -p 50000:50000 -v /var/jenkins_home:/var/j…

Java 泛型详细解析

本文将带你详细解析 Java 泛型,了解泛型的原理、常见的使用方法以及泛型的局限性,让你对泛型有更深入的了解。泛型的定义 泛型类的定义 下面定义了一个泛型类 Pair,它有一个泛型参数 T。 public class Pair<T> {private T start;private T end; }实际使用的时候就可以…

javafx-请求篇

OkHttpClient 基本使用步骤如下构建客户端对象OkHttpClient 构建请求Request 生成Call对象 Call发起请求(同步/异步)import java.io.IOException; import okhttp3.Call; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Req…

javafx-一个小demo

懒得讲了,直接看代码吧 pox.xml<?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://m…

一个小demo

懒得讲了,直接看代码吧 pox.xml<?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://m…

一个 Bug JDK 居然改了十年?

你敢相信么一个简单的Bug,JDK 居然花了十年时间才修改完成。赶快来看看到底是个什么样的 Bug?问题现象 今天偶然看到了一个 JDK 的 Bug,给大家分享一下。 假设现在有如下的代码: List<String> list = new ArrayList<>(); list.add("1"); Object[] ar…

崩溃列表数据库查询(可供参考)

首先去https://weikezhijia.feishu.cn/sheets/BIvxsKZhHhzpC6tDyoLcPE50n4d?sheet=9ikXjx 看库中导出指标,然后可以查到是rum_error表,然后去ors_rum_test服务器,ors_rum_test数据库,rum_error表去查询,结合点击全部按钮后查看F12 然后查看preView里的字段,结合着去查rum…

流量分析练习

flag明文 题目:key.pcapng查找flag或者flag{,我们在下图查找到所需要的flag本类题目特点:能够在字节流中直接查找到带有flag的字符串,不存在加解密或转换等,属于明文形式 2.flag编码 题目:64da5a4a1e024d198dfa307299965b6d.pcapng本题考到十六进制编码 将flag转成十六进…

哪里有 class 告诉我?

说明 本文中的 JVM 参数和代码在 JDK 8 版本生效。 哪里有用户类? 用户类是由开发者和第三方定义的类,它是由应用程序类加载器加载的。 Java 程序可以通过CLASSPATH 环境变量,JVM 启动参数 -cp 或者 -classpath 指定用户需要加载的类的路径。这两个配置的优先级从低到高,后…