首页 > 编程语言 >java的SPI机制

java的SPI机制

时间:2024-02-08 16:46:26浏览次数:35  
标签:ProgrammingLanguageService java iterator ServiceLoader SPI 机制 public 加载

参考https://blog.csdn.net/qq_52423918/article/details/130968307

1 概念

Java SPI(Service Provider Interface)是Java官方提供的一种服务发现机制,它允许在运行时动态地加载实现特定接口的类,而不需要在代码中显式地指定该类,从而实现解耦和灵活性。

2 实现原理

Java SPI 的实现原理基于 Java 类加载机制和反射机制。

这里会用到java.util.ServiceLoader类加载器。当使用 ServiceLoader.load(Class<T> service) 方法加载服务时,会检查 META-INF/services 目录下是否存在以接口全限定名命名的文件。如果存在,则读取文件内容,获取实现该接口的类的全限定名,并通过 Class.forName() 方法加载对应的类。

在加载类之后,ServiceLoader 会通过反射机制创建对应类的实例,并将其缓存起来。

这里涉及到一个懒加载迭代器的思想:
当我们调用 ServiceLoader.load(Class<T> service) 方法时,并不会立即将所有实现了该接口的类都加载进来,而是返回一个懒加载迭代器。
只有在使用迭代器遍历时,才会按需加载对应的类并创建其实例。

3 例子

服务接口ProgrammingLanguageService

public interface ProgrammingLanguageService {
    void study();
}

两个实现类

public class JavaServiceImpl implements ProgrammingLanguageService {
    @Override
    public void study() {
        System.out.println("开始学习java");
    }
}

public class PythonServiceImpl implements ProgrammingLanguageService {
    @Override
    public void study() {
        System.out.println("开始学习python");
    }
}

创建META-INF/services路径和com.demo.szj.ProgrammingLanguageService文件,内容

com.demo.szj.JavaServiceImpl
com.demo.szj.PythonServiceImpl

启动类

public class ServiceLoaderTest {
    public static void main(String[] args) {
        ServiceLoader<ProgrammingLanguageService> serviceLoader = ServiceLoader.load(ProgrammingLanguageService.class);
        Iterator<ProgrammingLanguageService> iterator = serviceLoader.iterator();
        while(iterator.hasNext()) {
            ProgrammingLanguageService service = iterator.next();
            service.study();
        }
    }
}

执行结果

我们看到,虽然我们没有创建这两个服务类,但是通过SPI机制,可以成功创建其实例。

 

标签:ProgrammingLanguageService,java,iterator,ServiceLoader,SPI,机制,public,加载
From: https://www.cnblogs.com/zhenjingcool/p/18011918

相关文章

  • 对Xcode Tools实现机制的一点思考
    场景在编译wine前,执行.configure检查依赖项是否都满足条件,发现bison的版本较低。检查发现存在一个/usr/bin/bison,但是从未安装过这一命令,所以考虑到是XTools中携带的,检查后发现确实如此然后就又一次引发了我对于XTool的疑问,/usr/bin/下和XTools中包含的相同可执行程序,不是以软......
  • Java中的审批流:BPMN与Flowable
    最近闲来无事,研究了一下工作流框架。找到了一条可以实现审批流程的技术方向。我选择的后端工作流框架是Flowable,看文档应该是属于Activity的一个分支吧。使用教程文档地址在:GettingStarted·FlowableOpenSourceDocumentation(用百度/必应搜索,搜到的是Flowable的官网,最后这个......
  • Java反射(learning)
    Java-reflectionJava反射(Reflection)是Java语言的一个特性,它允许程序在运行时检查和修改内部类的行为。通过反射,可以获取类的构造器、方法、字段等成员的信息,并且可以动态地创建对象、调用方法、访问和修改字段。Java反射主要涉及到以下几个类:java.lang.Class:代表一个类,每个......
  • 解析Sermant热插拔能力:服务运行时动态挂载JavaAgent和插件
    本文分享自华为云社区《服务运行时动态挂载JavaAgent和插件——Sermant热插拔能力解析》,作者:华为云高级软件工程师栾文飞一、概述Sermant是基于Java字节码增强技术的无代理服务网格,其利用Java字节码增强技术,为宿主应用程序提供服务治理功能,以解决大规模微服务场景中的服务治理......
  • 深入理解 Java 循环结构:while、do while、for 和 for-each 循环
    Java循环循环可以执行一个代码块,只要达到指定的条件。循环很方便,因为它们节省时间,减少错误,并使代码更易读。JavaWhile循环while循环会循环执行一个代码块,只要指定的条件为真:语法while(condition){//要执行的代码块}在下面的示例中,只要变量(i)小于5,循环中的代码将......
  • Java 中的Collections工具类
    Collections工具类java.util.Collection集合接口java.util.Collections集合工具类,方便集合操作对List集合中元素排序,需要保证List集合中元素实现了Comparable接口Collections.synchronizedList(list);设置成线程安全的Collections.sort(wuGuis);进行排序importjava......
  • javascript 下载 application/octet-stream 文件
    functiondownloadFile(id){varxhr=newXMLHttpRequest();xhr.open('POST','https://localhost/api/app/isp-detection/'+id+'/download');xhr.responseType='blob';xhr.setRequestHeader('Cont......
  • 编程新手必学:Java运算符详解
    编程新手必学:Java运算符详解编程,这种强大的艺术形式,给我们带来了无穷的可能性。就像数学中的加减乘除,程序设计中也有一种类似的工具:运算符。作为一种编程语言,Java提供了一系列的运算符来执行各种基础和复杂的操作。在本文中,我将尝试解释Java中的各种运算符,并提供一些代码示例来说......
  • 【视频】互联网Java工程师面试突击训练(三季)
    视频下载地址 https://pan.quark.cn/s/c17e3da33a76目录一、Java集合包HashMap的底层数据结构是什么?JDK1.8中对hash算法和寻址算法是如何优化的?03.HashMap是如何解决hash碰撞问题的?04.说说HashMap是如何进行扩容的?05.ArrayList,LinkedList,TreeMap,LinkedHashMap,HashSet等底层......
  • Transformer训练机制
    前言关于Transformer原理与论文的介绍:详细了解Transformer:AttentionIsAllYouNeedPyTorch中实现Transformer模型前面介绍了,Transformer模型结构的实现,这里介绍下论文中提到的训练策略与设置。设置文件名为training.pyOptimizer优化器文中选择Adam优化器,\(\beta_1=0......