博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java spi_Java SPI(服务提供商接口)和ServiceLoader
阅读量:2546 次
发布时间:2019-05-11

本文共 6890 字,大约阅读时间需要 22 分钟。

java spi

Java SPI (Service Provider Interface) is the mechanism to load services dynamically. We can implement Java SPI in our application by following the specific set of rules and load the services using the ServiceLoader class.

Java SPI(服务提供者接口)是动态加载服务的机制。 通过遵循特定的规则集,我们可以在我们的应用程序中实现Java SPI,并使用ServiceLoader类加载服务。



Java SPI组件 (Java SPI Components)

There are four components in the SPI implementation.

SPI实现中包含四个组件。

  1. Service Provider Interface: An or that defines the contract for the service provider implementation classes.

    服务提供者接口 :定义服务提供者实现类的协定的或类。
  2. Service Providers: The implementation classes that actually provides the services.

    服务提供者 :实际提供服务的实现类。
  3. SPI Configuration File: A special file that provides the logic to look for the services implementations. The file name must be present in the META-INF/services directory. The file name should be exactly same as the service provider interface fully qualified name. Every line in the file have one implementation service class details, again the fully qualified name of the service provider class.

    SPI配置文件 :一个特殊的文件,提供查找服务实现的逻辑。 文件名必须存在于META-INF / services目录中。 文件名应与服务提供商接口标准名称完全相同。 文件中的每一行都有一个实现服务类详细信息,再次是服务提供者类的完全限定名称。
  4. ServiceLoader: The Java SPI main class that is used to load the services for a service provider interface. There are various utility methods in the ServiceLoader to get specific implementations, iterate through them, or reload the services again.

    ServiceLoader :Java SPI主类,用于为服务提供者接口加载服务。 ServiceLoader中有多种实用程序方法可用于获取特定的实现,对其进行迭代或重新加载服务。


Java服务提供者接口示例 (Java Service Provider Interfaces Examples)

The java.util.spi package provides a lot of service provider interfaces that can be implemented to provide services.

java.util.spi包提供了许多服务提供程序接口,可以将其实现以提供服务。

  1. ResourceBundleProvider, ResourceBundleControlProvider, and AbstractResourceBundleProvider: Service Provider interfaces and abstract class for Resource Bundle implementation classes.

    ResourceBundleProvider,ResourceBundleControlProvider和AbstractResourceBundleProvider:资源提供程序实现类的服务提供程序接口和抽象类。
  2. LocaleServiceProvider, CalendarDataProvider, CalendarNameProvider, CurrencyNameProvider, TimeZoneNameProvider, and LocaleNameProvider: for implementing Locale specific service providers.

    LocaleServiceProvider,CalendarDataProvider,CalendarNameProvider,CurrencyNameProvider,TimeZoneNameProvider和LocaleNameProvider:用于实现特定于区域设置的服务提供者。
Java SPI Interfaces List

Java SPI Interfaces List

Java SPI接口列表



Java SPI示例 (Java SPI Example)

Let’s create an implementation of SPI and load some services using the ServiceLoader class.

让我们创建SPI的实现,并使用ServiceLoader类加载一些服务。



1.服务提供商接口 (1. Service Provider Interface)

Let’s say we have a MessageServiceProvider interface that defines the contract for the service provider implementations.

假设我们有一个MessageServiceProvider接口,它定义了服务提供者实现的合同。

package com.journaldev.serviceproviders;public interface MessageServiceProvider {	void sendMessage(String message);}


2.服务提供商实施类 (2. Service Provider Implementation Classes)

We want to support email messages and push notification messages. So we will create two service provider implementations of MessageServiceProvider interface – EmailServiceProvider and PushNotificationServiceProvider.

我们希望支持电子邮件和推送通知消息。 因此,我们将创建MessageServiceProvider接口的两个服务提供程序实现-EmailServiceProvider和PushNotificationServiceProvider。

package com.journaldev.serviceproviders;public class EmailServiceProvider implements MessageServiceProvider {	public void sendMessage(String message) {		System.out.println("Sending Email with Message = "+message);	}}
package com.journaldev.serviceproviders;public class PushNotificationServiceProvider implements MessageServiceProvider {	public void sendMessage(String message) {		System.out.println("Sending Push Notification with Message = "+message);	}}


3.服务提供商配置文件 (3. Service Provider Configuration File)

The configuration file has to be created in the META-INF/services directory. Its name should be “com.journaldev.serviceproviders.MessageServiceProvider“. We will specify both the implementation classes in this file.

必须在META-INF / services目录中创建配置文件。 其名称应为“ com.journaldev.serviceproviders.MessageServiceProvider ”。 我们将在此文件中指定两个实现类。

com.journaldev.serviceproviders.EmailServiceProvidercom.journaldev.serviceproviders.PushNotificationServiceProvider


4.加载服务的ServiceLoader示例 (4. ServiceLoader Example to Load Services)

Finally, we have to load the services using the ServiceLoader class. Here is a simple test program showing its usage.

最后,我们必须使用ServiceLoader类加载服务。 这是一个显示其用法的简单测试程序。

package com.journaldev.test;import java.util.Optional;import java.util.ServiceLoader;import com.journaldev.serviceproviders.MessageServiceProvider;public class ServiceLoaderTest {	public static void main(String[] args) {		ServiceLoader
serviceLoader = ServiceLoader.load(MessageServiceProvider.class); for (MessageServiceProvider service : serviceLoader) { service.sendMessage("Hello"); } // using Java 8 Optional to get the first service Optional
firstService = serviceLoader.findFirst(); if (firstService.isPresent()) { firstService.get().sendMessage("Hello Friend"); } // using Java 8 forEach() method serviceLoader.forEach((service) -> service.sendMessage("Have a Nice Day!")); // Total Number of Loaded Services System.out.println(serviceLoader.stream().count()); }}

When we run the above program, we get the following output.

当我们运行上面的程序时,我们得到以下输出。

Sending Email with Message = HelloSending Push Notification with Message = HelloSending Email with Message = Hello FriendSending Email with Message = Have a Nice Day!Sending Push Notification with Message = Have a Nice Day!2

The below image shows our final project structure and SPI components.

下图显示了我们的最终项目结构和SPI组件。

Java SPI Example Project Structure

Java SPI Example Project Structure

Java SPI示例项目结构



ServiceLoader重要方法 (ServiceLoader Important Methods)

Let’s look at the important methods of the ServiceLoader class.

让我们看一下ServiceLoader类的重要方法。

  • load(): The static method to load the services of a particular SPI.

    load():加载特定SPI服务的静态方法。
  • findFirst(): returns the first service available for this service provider.

    findFirst():返回可用于该服务提供者的第一个服务。
  • : useful to run some code for every service provider in this service loader instance.

    :在此服务加载器实例中为每个服务提供者运行一些代码很有用。
  • : returns the stream of the service providers in this service loader.

    :返回此服务加载器中服务提供者的流。
  • iterator(): returns an of the service providers.

    iterator():返回服务提供者的 。
  • reload(): reloads the service providers. It’s useful when we change the service provider configurations on the fly and want to reload the services list.

    reload():重新加载服务提供商。 当我们即时更改服务提供商的配置并希望重新加载服务列表时,这很有用。


结论 (Conclusion)

Java SPI provides an easy way to dynamically configure and load the services in our application. However, it depends a lot on the service configuration file and any change in the file can break the application.

Java SPI提供了一种简单的方法来动态配置和加载应用程序中的服务。 但是,这在很大程度上取决于服务配置文件,并且文件中的任何更改都可能破坏应用程序。



参考资料 (References)



. 检出完整的项目。

翻译自:

java spi

转载地址:http://hyqzd.baihongyu.com/

你可能感兴趣的文章
34 帧动画
查看>>
二次剩余及欧拉准则
查看>>
Centos 7 Mysql 最大连接数超了问题解决
查看>>
thymeleaf 自定义标签
查看>>
关于WordCount的作业
查看>>
C6748和音频ADC连接时候的TDM以及I2S格式问题
查看>>
UIView的layoutSubviews,initWithFrame,initWithCoder方法
查看>>
STM32+IAP方案 实现网络升级应用固件
查看>>
用74HC165读8个按键状态
查看>>
jpg转bmp(使用libjpeg)
查看>>
linear-gradient常用实现效果
查看>>
sql语言的一大类 DML 数据的操纵语言
查看>>
VMware黑屏解决方法
查看>>
JS中各种跳转解析
查看>>
JAVA 基础 / 第八课:面向对象 / JAVA类的方法与实例方法
查看>>
Ecust OJ
查看>>
P3384 【模板】树链剖分
查看>>
Thrift源码分析(二)-- 协议和编解码
查看>>
考勤系统之计算工作小时数
查看>>
4.1 分解条件式
查看>>