Java中的SPI扩展机制(有demo)
参考连接:https://www.jianshu.com/p/3a3edbcd8f24
一、什么是SPI
SPI ,全称为 Service Provider Interface,是一种服务发现机制。它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。
二、设计的目的
肯定是为了扩展性,在不想修改源码的情况下,去替换系统原有的实现,代价最小也最灵活。
三、案例demo
先看看目录接结构

- spi-api模块:定义扩展接口
- spi-client模块:扩展的模块
- spi-test模块:测试模块
github地址:https://github.com/XiaoBinNumberOne/java-spi-demo
四、源码分析
首先看看ServiceLoader.java类结构

ServiceLoader.load,load方法创建了一些属性,重要的是实例化了内部类,LazyIterator。最后返回ServiceLoader的实例。
public final class ServiceLoader<S> implements Iterable<S>
private ServiceLoader(Class<S> svc, ClassLoader cl) {
//要加载的接口
service = Objects.requireNonNull(svc, "Service interface cannot be null");
//类加载器
loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;
//访问控制器
acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;
//先清空
providers.clear();
//实例化内部类
LazyIterator lookupIterator = new LazyIterator(service, loader);
}
}
查找实现类和创建实现类的过程,都在LazyIterator完成。当我们调用iterator.hasNext和iterator.next方法的时候,实际上调用的都是LazyIterator的相应方法。
public Iterator<S> iterator() {
return new Iterator<S>() {
public boolean hasNext() {
return lookupIterator.hasNext();
}
public S next() {
return lookupIterator.next();
}
.......
};
}
所以,我们重点关注lookupIterator.hasNext()方法,它最终会调用到hasNextService。
private class LazyIterator implements Iterator<S>{
Class<S> service;
ClassLoader loader;
Enumeration<URL> configs = null;
Iterator<String> pending = null;
String nextName = null;
private boolean hasNextService() {
//第二次调用的时候,已经解析完成了,直接返回
if (nextName != null) {
return true;
}
if (configs == null) {
//META-INF/services/ 加上接口的全限定类名,就是文件服务类的文件
//META-INF/services/com.viewscenes.netsupervisor.spi.SPIService
String fullName = PREFIX + service.getName();
//将文件路径转成URL对象
configs = loader.getResources(fullName);
}
while ((pending == null) || !pending.hasNext()) {
//解析URL文件对象,读取内容,最后返回
pending = parse(service, configs.nextElement());
}
//拿到第一个实现类的类名
nextName = pending.next();
return true;
}
}
分享学习是一件开心事
Java中的SPI扩展机制(有demo)的更多相关文章
- Dubbo中SPI扩展机制解析
dubbo的SPI机制类似与Java的SPI,Java的SPI会一次性的实例化所有扩展点的实现,有点显得浪费资源. dubbo的扩展机制可以方便的获取某一个想要的扩展实现,每个实现都有自己的name, ...
- 【Java】深入理解Java中的spi机制
深入理解Java中的spi机制 SPI全名为Service Provider Interface是JDK内置的一种服务提供发现机制,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用 ...
- 结合实战和源码来聊聊Java中的SPI机制?
写在前面 SPI机制能够非常方便的为某个接口动态指定其实现类,在某种程度上,这也是某些框架具有高度可扩展性的基础.今天,我们就从源码级别深入探讨下Java中的SPI机制. 注:文章已收录到:https ...
- java中的spi
JAVA中的SPI机制 1.SPI简介 SPI机制(Service Provider Interface)其实源自服务提供者框架(Service Provider Framework),是一种将服务接 ...
- Java中的SPI原理浅谈
在面向对象的程序设计中,模块之间交互采用接口编程,通常情况下调用方不需要知道被调用方的内部实现细节,因为一旦涉及到了具体实现,如果需要换一种实现就需要修改代码,这违反了程序设计的"开闭原则& ...
- java中的动态代理机制
java中的动态代理机制 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现 ...
- java中的安全模型(沙箱机制)
java中的安全模型(沙箱机制) java安全沙箱(一)之ClassLoader双亲委派机制 java安全沙箱(二)之.class文件检验器 java安全沙箱(三)之内置于Java虚拟机(及语言)的安 ...
- Java中的内存处理机制和final、static、final static总结
Java中的内存处理机制和final.static.final static总结 装载自:http://blog.csdn.net/wqthaha/article/details/20923579 ...
- 深度剖析java中JDK动态代理机制
https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...
随机推荐
- Python--day61 PyCharm连接MySQL工具的使用
第一步:连接mysql数据工具的位置 第二步:选定数据库 第三步:下载驱动 第四步:连接数据库配置 第五步:在pycharm中查看数据库中的表 第六步:添加数据 第七步:打开用sql语句操作数据库的界 ...
- solaris 10 基本使用
1. 新增用户 注释掉home行# cat /etc/auto_master # # Copyright 2003 Sun Microsystems, Inc. All rights reserved ...
- 【codeforces 761C】Dasha and Password(动态规划做法)
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- jmeter登录配置
前言: jmeter, Apache下的测试工具, 常用来进行压测, 项目中, 接口通常都需要进行登录才能被调用, 直接调用将提示"登录失效", 下面介绍如何在jmeter中配置参 ...
- dotnet 通过 WMI 获取系统安装软件
本文告诉大家如何通过 WMI 获取系统安装的软件,这个方法不能获取全部的软件 通过 Win32_Product 可以获取系统安装的软件 var mc = "Win32_Product&quo ...
- 2019-9-24-dotnet-remoting-抛出异常
title author date CreateTime categories dotnet remoting 抛出异常 lindexi 2019-09-24 15:39:50 +0800 2018- ...
- Cannot destructure property `createHash` of 'undefined' or 'null'(next服务端渲染引入next-less错误).
next中引入@zeit/next-less因next版本过低(webpack4之前的版本)无法执行next-less内置的mini-css-extract-plugin mini-css-extra ...
- CSS 高度居中方案
实现高度自适应并且上下居中 <div id="wrap"> <div class="box">DemoSeat</div> ...
- [竞赛]Beat Matching(对拍)
对拍的基本理论这里恕我不一一叙述,不会的请转身到这里:http://blog.csdn.net/code12hour/article/details/51252457 分为以下几个部分: 1.暴力伪标 ...
- Visual Studio Team Services使用教程【3】:默认团队权限说明
2017.4.23之后建议朋友看下面的帖子 TFS2017 & VSTS 实战(繁体中文视频) Visual Studio Team Services(VSTS)与敏捷开发ALM实战关键报告( ...