一个服务(service)通常指的是已知的接口或者抽象类,服务提供方就是对这个接口或者抽象类的实现,然后按spi标准存放到资源路径META-INF/services目录下,文件的命名为该服务接口的全限定名。如有一个服务接口com.test.Service,其服务实现类为com.test.ChildService,那此时需要在META-INF/services中放置文件com.test.Service,其中的内容就为该实现类的全限定名com.test.ChildService,有多个服务实现,每一行写一个服务实现,#后面的内容为注释,并且该文件只能够是以UTF-8编码。
这种实现方式,感觉和我们通常的开发方式差不多,都是定义一个接口,然后子类实现父类中定义的方法,为什么要搞这么一套标准以及单独搞一个配置文件?这种方式主要是针对不同的服务提供厂商,对不同场景的提供不同的解决方案制定的一套标准,举个简单的例子,如现在的JDK中有支持音乐播放,假设只支持mp3的播放,有些厂商想在这个基础之上支持mp4的播放,有的想支持mp5,而这些厂商都是第三方厂商,如果没有提供SPI这种实现标准,那就只有修改JAVA的源代码了,那这个弊端也是显而易见的,也就是不能够随着JDK的升级而升级现在的应用了,而有了SPI标准,SUN公司只需要提供一个播放接口,在实现播放的功能上通过ServiceLoad的方式加载服务,那么第三方只需要实现这个播放接口,再按SPI标准进行打包成jar,再放到classpath下面就OK了,没有一点代码的侵入性。
这种实现方式,感觉和我们通常的开发方式差不多,都是定义一个接口,然后子类实现父类中定义的方法,为什么要搞这么一套标准以及单独搞一个配置文件?这种方式主要是针对不同的服务提供厂商,对不同场景的提供不同的解决方案制定的一套标准,举个简单的例子,如现在的JDK中有支持音乐播放,假设只支持mp3的播放,有些厂商想在这个基础之上支持mp4的播放,有的想支持mp5,而这些厂商都是第三方厂商,如果没有提供SPI这种实现标准,那就只有修改JAVA的源代码了,那这个弊端也是显而易见的,也就是不能够随着JDK的升级而升级现在的应用了,而有了SPI标准,SUN公司只需要提供一个播放接口,在实现播放的功能上通过ServiceLoad的方式加载服务,那么第三方只需要实现这个播放接口,再按SPI标准进行打包成jar,再放到classpath下面就OK了,没有一点代码的侵入性。
如xml-parse等都属于spi,我自己实践了一下,示例如下:
定义接口
package spi; /** * Service Provider Interface * META-INF\service\$interface full name * 内容为借口实现类全名 * @author liwenj */ public interface Developer { public String getPrograme(); }
实现接口
package spi; public class JavaDeveloper implements Developer { @Override public String getPrograme() { return "Java"; } }
实现接口的同时,需要在MANIFEST中声明实现
在META-INF\service目录下 创建文件,以接口全名为名,如"spi.Developer"
内容就是实现类的全名,可以存在多个
注意:在META-INF\service中声明好接口实现后,要打成一个jar包导入到工程的classpath中。jdk需要在Jar文件中的META-INF\service目录中搜索
使用实现
package spi; import java.util.ServiceLoader; public class DeveloperClient { public ServiceLoader<Developer> serviceloader = ServiceLoader.load(Developer.class); public static void main(String[] arg) { DeveloperClient devClient = new DeveloperClient(); Developer dev = devClient.getDeveloper(); System.out.println(dev.getPrograme()); } private Developer getDeveloper(){ Developer lastdev = null; for(Developer dev : serviceloader) { System.out.println("out." + dev.getPrograme()); lastdev = dev; } return lastdev; } }
相关推荐
采用jdk自带的spi实现spi(service provider interface)
记一次 JDK SPI 配置不生效的问题 → 这么简单都不会,还是回家养猪吧.doc
spi(Service Prodiver Interface) ###前提概述 在面向对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可插拔的原则。再者硬编码的不好这处还...
webservice基于JDK演示service与client以及所需jar,使用wsimport进行Stub生成
XFire1.2版本,其中修改了META-INF/services 目录下的javax.xml.ws.spi.Provider文件,解决因为jdk1.6和XFire的架包冲突问题
sunjce_provider.jar
JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11安装包,JDK11安装包JDK11...
jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助文档jdk8帮助...
mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk1.8安装包!mac系统jdk...
jdk7 jdk8 jdk9 jdk10 jdk11 jdk12 jdk13 jdk14 (win-64位) 资源共享
bcprov-ext-jdk15on-1.54.jar、bcprov-jdk15on-1.54.jar和ssl-provider-jvm16-0.2.jar附件下载
JDK大全 JDK1.6 JDK1.7 JDK1.8 JDK1.9 JDK10 JDK11 JDK12
jdk内存设置 jdk内存设置 jdk内存设置 jdk内存设置 jdk内存设置 jdk内存设置
JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。此包已经合并sun源码,直接导入即可。
jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk配置jdk...
JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK11、JDK...
安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装JDK安装...
centos搭建jdk tomcat my5.6自启动服务
官网 jdk6,jdk7,jdk8,jdk9,jdk10 windox 32位、64位、linux 32位、64位 百度云。
Linux更换JDK+weblogic更换JDK 全局更换JDK Linux更换JDK+weblogic更换JDK 全局更换JDK