jdk SPI机制

什么是SPI

SPI(Service Provider Interface)服务提供接口,是指的一种服务发现机制,为某个特定的接口寻找服务的实现。在大规模的软件开发中经常采用这样的机制,实现模块之间基于接口编程,隐藏其实现细节,不同的服务提供商进行扩展实现,最终实现无需修改代码即可调用,实现完全无代码入侵。


JDK自带的SPI实例

JDK6以后提供了java.util.ServiceLoader类来实现从配置文件中加载子类或者接口的实现类。

从JDK API文档中我们可以知道实现起来相当简单,只需四步:

1.定义接口

package com.xxz.service;

public interface HelloService {
	
	public String sayHello();

}

2.写2个实现类,必须是有无构造函数的类

package com.xxz.service.impl;

public abstract class AbstractServiceImpl {
	
	//定义一些实现类都需要的属性
	private String name;
	
	public void func(String name){
		this.name = name;
	}

}

package com.xxz.service.impl;

import com.xxz.service.HelloService;

public class HelloServiceImpl1 extends AbstractServiceImpl implements HelloService{

	public String sayHello() {
		return "HelloServiceImpl1 sar hello!";
	}
}
package com.xxz.service.impl;

import com.xxz.service.HelloService;

public class HelloServiceImpl2 extends AbstractServiceImpl implements HelloService {

	public String sayHello() {
		return "HelloServiceImpl2 say hello!";
	}

}
3.在资源目录 META-INF/services 中放置提供者配置文件,文件名为文件名称为接口类的完整包路径和类名
com.xxz.service.impl.HelloServiceImpl1
com.xxz.service.impl.HelloServiceImpl2

4.测试调用

package com.xxz.service;

import java.util.ServiceLoader;

public class MainBootstrap {

	public static void main(String[] args) {
		ServiceLoader<HelloService> loadServices = ServiceLoader.load(HelloService.class);
		for(HelloService helloService : loadServices){
			System.out.println(helloService.sayHello()); 
		}
		
	}

}

执行后打印结果:

HelloServiceImpl1 sar hello!
HelloServiceImpl2 say hello!

JDK自带的ServiceLoader功能比较弱,只提供了如下几个方法:

1.reload:清除服务实例缓存,重新加载;

2.iterator:延迟方式加载服务,按配置的顺序生成服务实例;

3.load:从上下文加载器(ContextClassLoader)加载。

4.loadInstalled,系统加载器(SystemClassLoader)优先,没有则从上下文加载器加载。

实际上,JDK自带的ServiceLoader并不能满足开发的需求,例如单例服务,按别名使用指定的服务实现,优先级控制等等。

本文所涉及的源码:https://download.csdn.net/download/xiongxianze/10453611





猜你喜欢

转载自blog.csdn.net/xiongxianze/article/details/80544267