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 机制实现解耦与本地化
相关推荐
SPI 机制的主要思想是解耦,通过提供一个标准接口,允许第三方提供实现类,而无需在程序中硬编码。SPI 机制广泛应用于许多框架和库中,如 Dubbo、Spring、SpringBoot 等。 SPI 机制的核心组件是 ServiceLoader,...
总结来说,Java SPI机制是一种强大的服务发现和加载工具,它促进了服务接口和服务实现的解耦,提高了代码的可扩展性和可维护性。通过定义服务接口,编写实现类,并在配置文件中指定实现,我们可以在运行时动态地加载...
Java SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许JVM在运行时动态加载服务提供商。这个机制使得开发者可以扩展应用的功能,而无需修改原有代码。SPI的核心概念在于,服务接口由主程序...
总的来说,Java类加载机制和SPI机制是Java实现模块化编程和框架开发的重要手段。通过类加载机制,可以保证Java应用的类型安全和动态加载的需求;而SPI机制则提供了一种通用的方式来扩展Java平台功能,使得Java开发者...
SPI 机制的核心思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,能够实现解耦。 SPI 机制的实现原理是通过在 classpath 下的 META-INF/services/ 目录中创建一个以服务接口命名的文件,该文件...
总结,Java SPI是一个强大的插件机制,通过它可以轻松实现模块化设计,提高软件的可扩展性和灵活性。`spitest`项目可能是一个用于演示如何使用和配置SPI的示例,可以帮助开发者更好地理解和应用SPI机制。
本项目"采用Java SPI和Spring factories来实现插件化的demo"旨在展示这两种技术如何协同工作,实现插件化的应用程序设计。 首先,我们深入理解Java SPI。在Java中,SPI通常涉及到`META-INF/services`目录下的特定...
1.只需要在controller层增加自定义@RequestLog注解就可以实现了。 @RequestLog功能参数如下: 功能一:是否记录请求参数 功能二:是否记录请求日志 功能三:是否记录返回值 功能四:是否以debug形式记录 功能五:日志类型 ...
SPI(Service Provider Interface)是Java平台提供的一种服务发现机制,允许第三方开发者为已存在的接口提供实现。在Android系统中,虽然没有直接使用Java SPI,但Android的组件化思想与SPI有相似之处,尤其是在构建...
SPI机制使得开发者可以扩展程序的功能,而无需修改原代码,极大地提高了软件的可扩展性和模块化。 标题“Java SPI 学习记录”表明我们将探讨这个重要的Java特性,并分享学习过程中的一些理解和实践。这篇博客可能...
SPI(Service Provider Interface)是Java提供的一种服务发现和服务使用的机制,它允许开发者通过定义接口并在配置文件中指定实现类的方式,动态地加载服务实现。SPI的思想核心在于解耦,使得服务使用者无需关注服务...
在Java编程中,接口是实现软件解耦的关键工具。接口定义了一组方法,但不包含具体实现,使得类可以通过实现接口来遵循特定的行为规范。这种设计模式有助于提高代码的灵活性,可维护性和可扩展性。在本示例中,我们将...
SPI机制的主要思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,其核心思想就是解耦。 在Java中,SPI机制主要通过META-INF/services/目录里的配置文件来实现服务的提供和发现。当服务的提供者...
SPI,全称Service Provider ...总之,JDK的SPI机制为Java应用提供了一种灵活、可扩展的组件模型,极大地增强了软件的模块化和可维护性。理解并熟练运用SPI,对于开发大型复杂系统或构建插件化框架具有重要意义。
这个机制使得开发者可以将核心应用与可插拔的组件分离开来,提高了软件的可扩展性和模块化。 在Java中,SPI的核心接口位于`java.util.ServiceLoader`类中。它提供了一种通过读取`META-INF/services/`目录下的配置...
本文将介绍 Bridge 模式,它是一种结构型设计模式,用于解耦抽象与实现,增强软件系统的灵活性和可扩展性。 二、Bridge 设计模式的别名 Handle/Body 三、Bridge 设计模式的意图 Bridge 设计模式是 Java 中的一种结构...