Java SPI

摘要:
在java.util.ServiceLoader的文档里有比较详细的介绍。简单的总结下javaspi机制的思想。  2.jdbc    jdbc4.0以前,开发人员还需要基于Class.forName的方式来装载驱动,jdbc4也基于spi的机制来发现驱动提供商了,可以通过META-INF/services/java.sql.Driver文件里指定实现类的方式来暴露驱动提供者。
一、什么是Java SPI?

  SPI的全名为Service Provider Interface.大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的。在java.util.ServiceLoader的文档里有比较详细的介绍。简单的总结下java spi机制的思想。我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。

二、SPI具体约定

  java spi的具体约定为:当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。jdk提供服务实现查找的一个工具类:java.util.ServiceLoader。

三、应用场景

  1.common-logging

    apache最早提供的日志的门面接口。只有接口,没有实现。具体方案由各提供商实现, 发现日志提供商是通过扫描 META-INF/services/org.apache.commons.logging.LogFactory配置文件,通过读取该文件的内容找到日志提工商实现类。只要我们的日志实现里包含了这个文件,并在文件里制定 LogFactory工厂接口的实现类即可。

  2.jdbc

    jdbc4.0以前, 开发人员还需要基于Class.forName("xxx")的方式来装载驱动,jdbc4也基于spi的机制来发现驱动提供商了,可以通过META-INF/services/java.sql.Driver文件里指定实现类的方式来暴露驱动提供者。

四、案例说明

  一个内容管理系统有一个搜索模块。是基于接口编程的。搜索的实现可能是基于文件系统的搜索,也可能是基于数据库的搜索

  接口定义如下:

1 packagemy.xyz.spi;    
2 importjava.util.List;    
3 public interfaceSearch {    
4    publicList serch(String keyword);    
5 }      

A公司采用文件系统搜索的方式实现了 Search接口,B公司采用了数据库系统的方式实现了Search接口

A公司实现的类 com.A.spi.impl.FileSearch

B公司实现的类 com.B.spi.impl.DatabaseSearch

那么A公司发布 实现jar包时,则要在jar包中META-INF/services/my.xyz.spi.Search文件中写下如下内容

     com.A.spi.impl.FileSearch

那么B公司发布 实现jar包时,则要在jar包中META-INF/services/my.xyz.spi.Search文件中写下如下内容

    com.B.spi.impl.DatabaseSearch
1 packagecom.xyz.factory;    
2 importjava.util.Iterator;    
3 importjava.util.ServiceLoader;    
4 importmy.xyz.spi.Search;    
5 public classSearchFactory {    
6     privateSearchFactory() {    
7 }    
8     public staticSearch newSearch() {    
9         Search search = null;    
10         ServiceLoader<Search> serviceLoader = ServiceLoader.load(Search.class);    
11         Iterator<Search> searchs =serviceLoader.iterator();    
12         if(searchs.hasNext()) {    
13             search =searchs.next();    
14 }    
15         returnsearch;    
16 }    
17 }    
1 packagemy.xyz.test;    
2 importjava.util.Iterator;    
3 importjava.util.ServiceLoader;    
4 importcom.xyz.factory.SearchFactory;    
5 importmy.xyz.spi.Search;    
6 public classSearchTest {    
7     public static voidmain(String[] args) {    
8         Search search =SearchFactory.newSearch();    
9         search.serch("java spi test");    
10 }    
11 }   

免责声明:文章转载自《Java SPI》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇oracle instantclient_11_2插件安装Frp内网穿透安装教程#Frpc OpenWrt客户端安装#图形化管理下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

传统的SOA是否已经过时

  今天准备再聊下在当前微服务,中台和云原生技术下,传统的SOA是否已经过时这个话题。现在出去跟别人交流,谈到SOA的时候有些客户直接的反馈就是过时的技术怎么还在用?或者一说到SOA就认为过时了没必要采用,因此今天还是有必要就SOA是否过时进一步说明。 SOA的基本概念 我们可以来看下SOA本身的定义,即: SOA是一种架构方法,将传统的单片式应用打破...

几句话说清楚m.2和AHCI、NVME

【简单解说】 M是一代mini硬件接口,如MSATA,M.2是二代mini硬件接口,如M.2 NVME/SATA,  M.2支持传统SATA和PCI Express存储设备 M.2更多的指的是主板上的硬件接口(M.2接口,是Intel推出的一种替代MSATA新的接口规范,也就是我们以前经常提到的NGFF,即Next Generation Form Fact...

交换机端口安全Port-Security超级详解

一、Port-Security概述   在部署园区网的时候,对于交换机,我们往往有如下几种特殊的需求: 限制交换机每个端口下接入主机的数量(MAC地址数量) 限定交换机端口下所连接的主机(根据IP或MAC地址进行过滤) 当出现违例时间的时候能够检测到,并可采取惩罚措施   上述需求,可通过交换机的Port-Security功能来实现:  ...

【接口测试】-1.常用的接口测试工具(Postman、soupUI、Jemeter)

1)Postman 1.get/post请求-- postman获取用户信息1 get方式:可以直接在url中写入参数 Post方式:请求体可以写到URL或Body的form-data中写参数 2. 添加header--postman获取用户信息2 需要在Headers中填入响应的信息,如:Content-Typeàapplication/json...

服务对外提供接口以供不同站点之间使用:Spring Cloud Feign使用记录及携带token请求

  在开发 Spring Cloud 微服务的时候,我们知道,服务之间都是以 HTTP 接口的形式对外提供服务的,因此消费者在进行调用的时候,底层就是通过 HTTP Client 的这种方式进行访问。当然我们可以使用JDK原生的 URLConnection、Apache 的 HTTP Client、Netty 异步 Http Client,Spring 的...

《设计模式之禅》六大设计原则2

接口隔离原则 接口隔离原则的定义 接口分为两种: ● 实例接口(Object Interface),在Java中声明一个类,然后用new关键字产生一个实 例,它是对一个类型的事物的描述,这是一种接口。Java中的类也是一种接口。 ● 类接口(Class Interface),Java中经常使用的interface关键字定义的接口。 那什么是隔离呢?它有两种...