Java SPI 机制实现解耦与本地化
SPI 是 Java 提供的一种服务加载方式,全名为 Service Provider Interface,可以避免在 Java 代码中写死服务的提供者,而是通过 SPI 服务加载机制进行服务的注册和发现。通过这种方式,可以基于接口编程,实现多个模块的解耦。
SPI 机制实现解耦
如下的示例展示了通过 ServiceLoader 类加载指定接口的所有服务提供者并进行调用的简单实现。
1、定义接口 test.DirMonitor,包含一个方法 start();
2、实现接口 test.DirMonitor,定义两个实现类 test.ObserverMonitor 和 test.LoopMonitor;
3、设置接口的实现类列表。创建目录 META-INF/services/,新建文件 test.DirMonitor,内容如下:
test.ObserverMonitor
test.LoopMonitor
4、在程序中通过 ServiceLoader 类加载 test.DirMonitor 接口的实现类,并遍历所有实现类,调用 start() 方法;

从上面的示例可以看出,在代码中仅仅使用到了接口 test.DirMonitor,并没有在代码中使用到具体实现类。通过这种方法,可以实现解耦,接口与实现类可以由不同的开发人员实现,编译到不同的 jar 包中,甚至实现插件的定义与开发。
spi 包的本地化扩展
java.util.spi 包提供了一些抽象类,可以用于扩展 Java 的本地化服务。本地化 SPI 的使用方法与 ServiceLoader 的 SPI 稍有不同,本地化 SPI 的实现需要打包成 jar 包后,放置于运行的 jre/lib/ext 目录下方能生效。
java.util.spi 包提供的抽象类如下所示:
CalendarDataProvider:为 java.util.Calendar 类的参数提供本地化数据的服务提供者的抽象类;
CalendarNameProvider:为 java.util.Calendar 类的字段提供本地化名称的服务提供者的抽象类;
CurrencyNameProvider:为 java.util.Currency 提供本地化货币符号名称的服务提供者的抽象类;
LocaleNameProvider:为 java.util.Locale 类提供本地化名称的服务提供者的抽象类;
LocaleServiceProvider:其他服务提供者抽象类的基类;
ResourceBundleControlProvider:服务接口,用于提供 java.util.ResourceBundle.Control 的实现类;
TimeZoneNameProvider:为 java.util.TimeZone 提供本地化时区的服务提供者的抽象类。
以 CalendarDataProvider 为例,该抽象类用于实现本地化的日历数据。在下面的例子中,CalendarDataProviderSPI 类设置了每周的第一天为 3,一年中第一周所需的最少天数为 6。

按照 SPI 的要求,在 META-INF/services/ 下建立 java.util.spi.CalendarDataProvider 文件,并写入 testspi.CalendarDataProviderSPI。打包为 jar 后,放置于 jre/lib/ext 目录后,执行下面的代码,则打印的数字分别为 3 和 6,而不再是默认的 1 和 1。

总结
Java 通过 SPI 机制为我们提供了一种服务发现机制。通过在 META-INF/services/ 目录下创建以接口全限定名为名称的文件,并在文件中每行写入一个服务提供者的全限定名,Java 可以发现并创建服务提供者的实例。
通过 ServiceLoader 我们可以获取指定接口的所有服务提供者,并实现接口调用与服务提供者的解耦。通过实现 spi 包的抽象接口,并放置于 jre/lib/ext 目录下,可以实现 Java 的本地化。
原文地址:Java SPI 机制实现解耦与本地化

Java SPI 机制实现解耦与本地化的更多相关文章
- JDK源码解析之Java SPI机制
1. spi 是什么 SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件. 系统设计的各个抽象,往往 ...
- Java SPI机制实战详解及源码分析
背景介绍 提起SPI机制,可能很多人不太熟悉,它是由JDK直接提供的,全称为:Service Provider Interface.而在平时的使用过程中也很少遇到,但如果你阅读一些框架的源码时,会发现 ...
- 组件化框架设计之Java SPI机制(三)
阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 本篇文章将从深入理解java SPI机制来介绍组件化框架设计: ...
- Java spi机制浅谈
最近看到公司的一些框架和之前看到的开源的一些框架的一些服务发现和接入都采用了java的spi机制. 所以简单的总结下java spi机制的思想. 我们系统里抽象的各个模块,往往有很多不同的实现方案,比 ...
- 聊聊Java SPI机制
一.Java SPI机制 SPI(Service Provider Interface)是JDK内置的服务发现机制,用在不同模块间通过接口调用服务,避免对具体服务服务接口具体实现类的耦合.比如JDBC ...
- Java SPI机制详解
Java SPI机制详解 1.什么是SPI? SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制.SPI是一种动态替换发现的机制, 比如有个 ...
- Java SPI机制和使用示例
JAVA SPI 简介 SPI 是 Java 提供的一种服务加载方式,全名为 Service Provider Interface.根据 Java 的 SPI 规范,我们可以定义一个服务接口,具体的实 ...
- Java SPI机制,你了解过吗?
Life moves pretty fast,if you don't stop and look around once in a while,you will miss it 为什么需要SPI? ...
- java SPI机制
1. SPI是Service Provider Interfaces的简称.根据Java的SPI规范,我们可以定义一个服务接口,具体的实现由对应的实现者去提供,即Service Provider(服务 ...
随机推荐
- win10 配置 maven | 下载与配置
<!-- 阿里云仓库 --> <mirrors> <mirror> <id>nexus-aliyun</id> <mirrorOf&g ...
- Python-迭代协议-__iter__ __next__ iter next yield
iter 本质是for循环调用的实质,for循环通过调用这个函数返回可迭代对象生成器形式,开始迭代取值捕获StopIteration错误退出循环 for循环首先找__iter__方法,然后再找 __g ...
- Python-在列表、字典中筛选数据
实际问题有哪些? 过滤掉列表[3,9,-1,10.-2......] 中负数 筛选出字典{'li_ming':90,'xiao_hong':60,'li_kang':95,'bei_men':98} ...
- 未能找到元素“appender”的架构信息
在App.config写入log4net的配置信息,然后错误列表就出现了一堆的消息提示. 未能找到元素"appender-ref"的架构信息 未能找到元素"appende ...
- #error: Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]
转载:https://www.cnblogs.com/cvwyh/p/10570920.html 错误 在使用VS编译文件时出现了如下错误: #error: Building MFC applicat ...
- Tensorflow学习笔记No.5
tf.data卷积神经网络综合应用实例 使用tf.data建立自己的数据集,并使用CNN卷积神经网络实现对卫星图像的二分类问题. 数据下载链接:https://pan.baidu.com/s/141z ...
- SpringBoot 优化
- 利用 yum 命令和 rpm 命令升级 Nginx 或者安装最新版本 Nginx
方法一:使用 yum 命令升级 Nginx 1.在配置 YUM 仓库的目录(/etc/yum.repos.d/)下新增文件 nginx.repo vi /etc/yum.repos.d/nginx. ...
- JVM 第五篇:命令行 JVM 故障处理工具
本文内容过于硬核,建议有 Java 相关经验人士阅读. 1. 引言 虽然我们前面介绍了各种图形化 JVM 故障处理工具,但是很多情况下,我们在处理问题的时候并没有图形化的操作环境可以使用,这时候,就需 ...
- 使用git 版本控制的代码在线修调试,如何还原
在线调试: 先切换成www用户进入项目的根目录比如/data/wwwroot/website su www cd /data/wwwroot/website vi ./api/controllers/ ...