SPI 说明:
SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。 目前有不少框架用它来做服务的扩展发现,
简单来说,它就是一种动态替换发现的机制, 举个例子来说, 有个接口,想运行时动态的给它添加实现,你只需要添加一个实现【可不是说程序跑起来你换个jar就会动态选择实现类】。
主要用途:模块之前完全解耦合【比如服务定义A 服务实现A1/服务实现A2 某一程序使用A服务,代码里面不需要写new A1() 或者new A2(),不想用的话,只需要从类路径异常想用的jar或者添加想用的jar包】
jdbc就是基于这块实现....
编写代码需要满足什么条件才可以使用?
1.定义接口
2.各种服务实现
3.关键:在实现类的jar中添加:META-INF/services/接口包名.接口名称 文件内容:实现类的包名.实现类的名称
4.访问...见代码
1.定义接口
2.各种实现
3.关键(贴图)【不一一贴了】
[img]http://dl2.iteye.com/upload/attachment/0130/8478/3a078653-ae18-3c28-b1ad-e0d697c4e945.png[/img]
4.访问
运行结果
==========DbSave=============
数据库方式保存,实现方式,请求参数:test
==========DbSave=============
==========FileSave=============
文件方式保存,实现方式,请求参数:test
==========FileSave=============
----------------------------------------------
---------整体代码间附件learnspi.zip
缺点:
根据文件中配置实例类,全部实例化,占用不必要的内存,
个人觉得:提供接口后,后面各个厂商的实现,各个厂商实现即可,也不会闲着没有瞎弄多个吧,不算缺点吧
这块的源码分析可以看看[url]https://www.jianshu.com/p/a6073e9f8cb4[/url],文档分析的很好!!!
跟了一下:根据接口名称去类路径找文件(含jar),找到相应的文件,读取内容,里面的配置即为实现类,根据class.for....来实例化,需要有默认的构造器
SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。 目前有不少框架用它来做服务的扩展发现,
简单来说,它就是一种动态替换发现的机制, 举个例子来说, 有个接口,想运行时动态的给它添加实现,你只需要添加一个实现【可不是说程序跑起来你换个jar就会动态选择实现类】。
主要用途:模块之前完全解耦合【比如服务定义A 服务实现A1/服务实现A2 某一程序使用A服务,代码里面不需要写new A1() 或者new A2(),不想用的话,只需要从类路径异常想用的jar或者添加想用的jar包】
jdbc就是基于这块实现....
编写代码需要满足什么条件才可以使用?
1.定义接口
2.各种服务实现
3.关键:在实现类的jar中添加:META-INF/services/接口包名.接口名称 文件内容:实现类的包名.实现类的名称
4.访问...见代码
1.定义接口
package com.learn.interfaces;
public interface SaveDataInterface {
/**
* 只是一个save方法,让其他模块去实现
* @param msg
*/
void save(String msg);
}
2.各种实现
package com.learn.service.save.imps;
import com.learn.interfaces.SaveDataInterface;
public class FileSaveDataSaveImpl implements SaveDataInterface {
public void save(String msg) {
System.out.println("==========FileSave=============");
System.out.println("文件方式保存,实现方式,请求参数:"+msg);
System.out.println("==========FileSave=============");
}
}
package com.learn.service.db;
import com.learn.interfaces.SaveDataInterface;
public class DbSaveDataImpl implements SaveDataInterface{
public void save(String msg) {
System.out.println("==========DbSave=============");
System.out.println("数据库方式保存,实现方式,请求参数:"+msg);
System.out.println("==========DbSave=============");
}
}
3.关键(贴图)【不一一贴了】
[img]http://dl2.iteye.com/upload/attachment/0130/8478/3a078653-ae18-3c28-b1ad-e0d697c4e945.png[/img]
4.访问
package com.test;
import java.util.Iterator;
import java.util.ServiceLoader;
import com.learn.interfaces.SaveDataInterface;
public class TestForSpi {
public static void main(String[] args) {
ServiceLoader<SaveDataInterface> serviceLoader = ServiceLoader.load(SaveDataInterface.class);
Iterator<SaveDataInterface> imps = serviceLoader.iterator();
SaveDataInterface imp;
while (imps.hasNext()) {
imp = imps.next();
imp.save("test");
}
}
}
运行结果
==========DbSave=============
数据库方式保存,实现方式,请求参数:test
==========DbSave=============
==========FileSave=============
文件方式保存,实现方式,请求参数:test
==========FileSave=============
----------------------------------------------
---------整体代码间附件learnspi.zip
缺点:
根据文件中配置实例类,全部实例化,占用不必要的内存,
个人觉得:提供接口后,后面各个厂商的实现,各个厂商实现即可,也不会闲着没有瞎弄多个吧,不算缺点吧
这块的源码分析可以看看[url]https://www.jianshu.com/p/a6073e9f8cb4[/url],文档分析的很好!!!
跟了一下:根据接口名称去类路径找文件(含jar),找到相应的文件,读取内容,里面的配置即为实现类,根据class.for....来实例化,需要有默认的构造器