JAVASPI机制详解使用方法_第1页
JAVASPI机制详解使用方法_第2页
JAVASPI机制详解使用方法_第3页
JAVASPI机制详解使用方法_第4页
JAVASPI机制详解使用方法_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第JAVASPI机制详解使用方法目录写在前面什么是SPI使用场景实现约定四种角色基于JAVA原生特性实现的JAVASPI机制的DEMO1.主要角色2.示例代码3.说明基于SPRINGBOOT实现的JAVASPI机制的DEMO

写在前面

JavaSPI提供了一种为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,SPI的核心思想就是解耦。

什么是SPI

SPI全称ServiceProviderInterface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。JavaSPI实际上是基于接口的编程+策略模式+配置文件组合实现的动态加载机制。在面向对象的编程与设计中,一般推荐模块之间要基于接口编程,模块之间不对实现类进行硬编码,一旦代码里涉及了具体的实现类,就违反了可拔插的原则,如果需要替换另外一种实现,就需要修改代码。

使用场景

使用JavaSPI机制的优势是实现解耦,使得第三方服务模块的装配控制的逻辑与调用者的业务代码分离,而不是耦合在一起,应用程序可以根据实际业务情况启用框架扩展或替换框架组件,常见的场景如下:

(1).JDBC加载不同类型的驱动

(2).SLF4J对Log4j/Logback的支持

实现约定

(1).服务提供者提供接口的具体实现,在JAVA包的META-INF/services目录下创建一个以接口全限定名为命名的文件,内容为实现类的全限定名;

(2).接口具体实现类所在的JAR包需要放在主程序的CLASSPATH中;

(3).主程序通过java.util.ServiceLoder动态加载具体的实现模块,它通过扫描META-INF/services目录下的配置文件,找到具体实现类并把它加载到JVM中;

(4).SPI的实现类必须携带一个不带参数的构造函数。

四种角色

(1).提供某种功能的接口(SLF4J提供了一组接口类)

(2).提供某种功能接口的具体实现(每个具体的实现需要包含:META-INF/services目录下创建一个以接口全限定名为命名的文件,内容为实现类的全限定名。Log4j/Logback提供了具体的实现)

(3).提供发现和加载CLASSPATH中所有的接口具体实现的对象

(4).客户端(接口的使用者)

关于JAVASPI详细的介绍请看:JAVA-SPI机制使用详解(一)

基于JAVA原生特性实现的JAVASPI机制的DEMO

1.主要角色

主要角色有:接口、多个实现类以及测试客户端,在每个实现类中需要创建信息文件:resources/META-INF/services/接口全限定名一致的文件。接口、多个实现类以及客户端分别在不同的MODULE中。

2.示例代码

①.接口:

packagecom.hadoopx.javax.spi;

publicinterfaceCoder{

publicStringwrite();

②.第一个实现类:

packagecom.hadoopx.javax.spi;

publicclassJavaerimplementsCoder{

publicStringwrite(){

return"I'MJAVACODER,USEJAVATOWRITEEVERYTHING.";

创建信息说明文件:resources/META-INF/services/com.hadoopx.javax.spi.Coder,

里面的内容为:com.hadoopx.javax.spi.Javaer

③.第二个实现类:

packagecom.hadoopx.javax.spi;

publicclassRubyerimplementsCoder{

publicStringwrite(){

return"I'MRUBYCODER,USERUBYTOWRITEEVERYTHING.";

创建信息说明文件:resources/META-INF/services/com.hadoopx.javax.spi.Coder,

里面的内容为:com.hadoopx.javax.spi.Rubyer

④.客户端:

添加依赖:

dependencies

dependency

groupIdcom.hadoopx/groupId

artifactIdjavax-spi001-javaer/artifactId

version1.0-SNAPSHOT/version

/dependency

dependency

groupIdcom.hadoopx/groupId

artifactIdjavax-spi001-rubyer/artifactId

version1.0-SNAPSHOT/version

/dependency

/dependencies

客户端代码:

packagecom.hadoopx.javax.spi;

publicclassMyTest{

publicstaticvoidmain(String[]args){

ServiceLoaderCoders=ServiceLoader.load(Coder.class);

IteratorCoderiterator=s.iterator();

while(iterator.hasNext()){

Coderlang=iterator.next();

Stringcontent=lang.write();

System.out.println(content);

输出结果为:

IMJAVACODER,USEJAVATOWRITEEVERYTHING.

IMRUBYCODER,USERUBYTOWRITEEVERYTHING.

3.说明

在实际的使用过程中,需要指定不同的类型来创建不同的实现类实例。

基于SPRINGBOOT实现的JAVASPI机制的DEMO

注意:在每个实现类中不需要创建信息文件。

①.接口:

packagecom.hadoopx.javax.spi;

publicinterfaceCoder{

publicStringwrite();

②.第一个实现类:

packagecom.hadoopx.javax.spi;

@Service

@Primary

publicclassJavaerimplementsCoder{

publicStringwrite(){

return"I'MJAVACODER,USEJAVATOWRITEEVERYTHING.";

③.第二个实现类:

packagecom.hadoopx.javax.spi;

@Service

publicclassRubyerimplementsCoder{

publicStringwrite(){

return"I'MRUBYCODER,USERUBYTOWRITEEVERYTHING.";

④.客户端一:

添加依赖:

dependencies

dependency

groupIdcom.hadoopx/groupId

artifactIdjavax-spi002-javaer/artifactId

version1.0-SNAPSHOT/version

/dependency

dependency

groupIdcom.hadoopx/groupId

artifactIdjavax-spi002-rubyer/artifactId

version1.0-SNAPSHOT/version

/dependency

/dependencies

客户端代码:

@RestController

@RequestMapping("/t")

@Api(value="测试服务",description="该服务仅仅用于完成验证、学习和测试")

publicclassTestController{

//切换不同的服务

@Autowired

@Qualifier("javaer")

privateCodercoder;

@ApiOperation(value="测试",notes="基于SPRINGBOOT实现的JAVASPI机制的DEMO")

@GetMapping("/spi")

publicStringtest(){

System.out.println(coder.write());

return"ok";

输出结果为:

IMJAVACODER,USEJAVATOWRITEEVERYTHING.

⑤.客户端二:

有时会根据不同的情况,调用不同服务的方法,所以在客户端中需要多增加下面这个文件:

@Service

publicclassCoderContext{

//通过@Autowired把Coder所有的实现类注入到map(coders)中.

//Spring会查找应用的上下文里类型为Coder的Bean,并把查找到的Bean注入到MapString,Coder或者ListCoder中

@Autowired

MapString,Codercoders;

publicCodergetCoder(Stringkey){

returncoders.get(key);

客户端代码:

@RestController

@RequestMapping("/t")

@Api(value="测试服务",description="该服务仅仅用于完成验证、学习和测试")

publicclassTestController{

@Autowired

private

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论