`
wen866595
  • 浏览: 269016 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

java.util.ServiceLoader demo

    博客分类:
  • java
阅读更多

首先引用API中的说明文档:

 

一个简单的服务提供者加载设施。

 

服务 是一个熟知的接口和类(通常为抽象类)集合。服务提供者 是服务的特定实现。提供者中的类通常实现接口,并子类化在服务本身中定义的子类。服务提供者可以以扩展的形式安装在 Java 平台的实现中,也就是将 jar 文件放入任意常用的扩展目录中。也可通过将提供者加入应用程序类路径,或者通过其他某些特定于平台的方式使其可用。

 

为了加载,服务由单个类型表示,也就是单个接口或抽象类。(可以使用具体类,但建议不要这样做。)一个给定服务的提供者包含一个或多个具体类,这些类扩展了此服务类型 ,具有特定于提供者的数据和代码。提供者类 通常不是整个提供者本身而是一个代理,它包含足够的信息来决定提供者是否能满足特定请求,还包含可以根据需要创建实际提供者的代码。提供者类的详细信息高度特定于服务;任何单个类或接口都不能统一它们,因此这里没有定义任何这种类型。此设施唯一强制要求的是,提供者类必须具有不带参数的构造方法,以便它们可以在加载中被实例化。

 

通过在资源目录 META-INF/services 中放置提供者配置文件 来标识服务提供者。文件名称是服务类型的完全限定 二进制名称 。该文件包含一个具体提供者类的完全限定二进制名称列表,每行一个。忽略各名称周围的空格、制表符和空行。注释字符为 '#' ('\u0023' , NUMBER SIGN );忽略每行第一个注释字符后面的所有字符。文件必须使用 UTF-8 编码。

 

....还有其他的一些就不拷贝过来了。

 

 

从说明中可以看出,这个机制允许服务的声明与实现的分离,具体使用哪个实现可以在运行时才决定,使用哪个实现取决于是否部署了该实现。下面是个简单的demo。

 

1、首先定义一个表示服务的接口:

package learn.serviceLoader.service;

import java.util.ServiceLoader;

public abstract class SimpleService {
	public abstract void doService();

	private static boolean isInit = false;
	private static SimpleService service = null;

	public static final SimpleService getService() {
		if (!isInit) {
			ServiceLoader<SimpleService> serviceLoader = ServiceLoader
					.load(SimpleService.class);
			for (SimpleService s : serviceLoader) {
				service = s;
				break;
			}

			isInit = true;
		}

		return service;
	}
}

 

此接口定义了服务的能力,同时提供了工厂方法来获取服务的实例。这个工厂方法就是通过此机制来查找服务的实现的。

 

 

2、实现服务提供者。

package learn.serviceLoader.serviceimpl;

import learn.serviceLoader.service.SimpleService;

public class StandarService extends SimpleService {

	@Override
	public void doService() {
		System.out
				.println("i am standar service, i implement SimpleService, so you get here .");
	}
}

 就是实现服务接口的方法。

 

 

3、在服务提供者jar中下配置:

    a、建立一个META-INF文件夹,在META-INF文件夹下建立一个services文件夹;

    b、在services文件夹下建立服务配置文件,如:learn.serviceloader.service.SimpleService

        里面的内容就是提供者的全限定类名:learn.serviceLoader.serviceimpl.StandarService    # comment

 

 

4、服务的使用者:

package learn.serviceLoader.test;

import learn.serviceLoader.service.SimpleService;

public class TestServiceLoader {

	public static void main(String[] args) {
		SimpleService service = SimpleService.getService();
		service.doService();
		
		SimpleService service2 = SimpleService.getService();
		service2.doService();
	}
}

 服务的使用者通过服务接口的工厂方法来获取服务,使用者并不知道、也不需要知道使用的是哪个服务提供者。

 

 

对于复杂的使用,应该将服务的声明放在单独的api.jar包,不同的实现放在不同的jar,部署时只需要部署api.jar和特定的提供者jar包。此机制还支持  “reload ()   清除此加载器的服务者缓存,以重载所有服务者。”,应该可以预留方法,实现动态切换服务提供者。

 

 

这是个简单又强大的机制,可以方便地实现服务声明与实现的分离。

 

分享到:
评论

相关推荐

    JavaServiceProviderInterfaceDemo:Java 的 SPI(服务提供者接口)和 java.util.ServiceLoader 使用的简单演示

    提供spidemo.cloud.CloudService实用程序类来包装java.util.ServiceLoader操作。 搜索服务 演示伪“关键字搜索服务”提供程序。 为服务提供者定义spidemo.search.spi.Search接口。 提供spidemo.search.Search...

    spi-Demo.rar

    综上所述,"spi-Demo.rar"中的内容可能包括一个展示了如何定义服务接口、创建服务提供者、编写配置文件以及如何在应用中使用`ServiceLoader`加载服务的示例代码。通过这个Demo,学习者可以更好地理解和掌握Java SPI...

    java spi 可运行 demo

    3. **服务加载器**:Java SPI提供了`java.util.ServiceLoader`类,用于加载配置文件中的服务提供者,并实例化这些类。 ### 二、SPI工作流程 1. **查找配置文件**:`ServiceLoader`会去`META-INF/services`目录下...

    SPI入门级Demo(三:服务实现者-加法服务)

    这个机制在Java中主要由`java.util.ServiceLoader`类来实现。在本示例中,我们将探讨如何创建一个简单的SPI入门级Demo,具体是关于实现一个加法服务。 首先,理解SPI的基本流程: 1. **定义接口**:服务接口是所有...

    Java SPI Demo

    4. **加载服务**:使用`java.util.ServiceLoader`类来加载并实例化服务提供者。`ServiceLoader`会自动读取服务配置文件,并创建每个服务提供者的实例。 ```java ServiceLoader&lt;Plugin&gt; loader = ServiceLoader.load...

    SPI入门级Demo(四:服务实现者-乘法服务)

    4. **服务加载**:在程序中,我们可以通过`java.util.ServiceLoader`类来加载并使用SPI服务。下面是一个简单的加载和使用SPI服务的示例: ```java import java.util.ServiceLoader; public class SPIConsumer { ...

    SPI示例代码及实现方式

    在Java中,SPI的核心接口位于`java.util.ServiceLoader`类中。它提供了一种通过读取`META-INF/services/`目录下的配置文件来查找并加载服务提供商的方法。下面我们将详细介绍如何使用SPI,并给出示例代码。 首先,...

    java_spi_demo

    在java.util.ServiceLoader的文档里有比较详细的介绍。究其思想,其实是和"Callback"差不多。“Callback”的思想是在我们调用API的时候,我们可以自己写一段逻辑代码,传入到API里面,API内部在合适的时候会调用它,...

    数据库连接(主流).txt

    - `java.util.Properties`:用来存储配置信息,这里没有实际使用。 2. **获取数据库连接** - 使用`Class.forName()`方法加载指定的JDBC驱动。这里的`com.mysql.jdbc.Driver`是MySQL JDBC驱动的类名。 - 使用`...

    Java的Spi使用实例

    在`java.util.ServiceLoader`类的帮助下,我们可以方便地加载并使用这些服务提供者。下面我们将详细探讨Java SPI的工作原理、如何创建和使用SPI服务,以及一个具体的`SpiDemo`实例。 1. **SPI工作原理** - **配置...

    java SPI机制实现服务接口和服务实现分离源码Demo

    SPI机制的核心是`java.util.ServiceLoader`类,它允许我们按照约定在`META-INF/services`目录下创建配置文件,来指定哪些类实现了特定的服务接口。 服务接口定义:在SPI机制中,首先我们需要定义一个服务接口,这个...

    软件架构:SPI的Demo

    在Java中,SPI主要通过`java.util.ServiceLoader`类来实现。 在描述中提到了一个博客链接,虽然具体内容没有提供,但我们可以假设这个博客详细解释了如何创建和使用SPI的示例。通常,SPI的实现包括以下几个步骤: ...

    user-storage-spi-demo

    2. **ServiceLoader**:Java的`java.util.ServiceLoader` 类是实现SPI的关键。它提供了一种迭代方式来加载服务提供者。通过`ServiceLoader.load()`方法,我们可以加载符合特定接口的所有实现。 3. **接口与实现**:...

    SPI入门级Demo(二:契约即接口定义)

    首先,SPI的核心在于`java.util.ServiceLoader`类,它是Java SPI的入口点。通过这个类,我们可以方便地加载实现了指定接口的各个服务提供商。在SPI中,契约通常指的是接口,它定义了服务提供商必须遵循的行为规范。 ...

    深入学习Java中的SPI机制

    java.util.ServiceLoader首先实现了Iterable接口,所以它有迭代器的属性,这里主要都是实现了迭代器的hasNext和next方法。这里主要都是调用的lookupIterator的相应hasNext和next方法,lookupIterator是懒加载迭代器...

    dubbo-spiDemo:精神病

    JDK SPI的核心类是`java.util.ServiceLoader`,它负责加载`META-INF/services/`目录下对应接口名称的配置文件,并根据配置文件中的类名创建服务实现的实例。配置文件的格式通常是每行一个类名,这些类实现了指定的...

Global site tag (gtag.js) - Google Analytics