聊聊Java SPI机制
一、Java SPI机制
SPI(Service Provider Interface)是JDK内置的服务发现机制,用在不同模块间通过接口调用服务,避免对具体服务服务接口具体实现类的耦合。比如JDBC的数据库驱动模块,不同数据库连接驱动接口相同但实现类不同,在使用SPI机制以前调用驱动代码需要直接在类里采用Class.forName(具体实现类全名)的方式调用,这样调用方依赖了具体的驱动实现,在替换驱动实现时要修改代码。而采用SPI机制后,在驱动jar包的META-INF/services下面新建一个驱动接口全名的UTF-8编码的文件,里面写上具体实现类的全名,这样调用方通过Java 的ServiceLoad接口动态的去加载接口的实现类,从而达到替换驱动实现不用修改代码的效果,如下代码:
public static void main(String[] args) {
ServiceLoader<DriverService> serviceLoader = ServiceLoader.load(DriverService.class);
for (DriverService driverService: serviceLoader){
System.out.println(driverService.getName());
}
}
使用步骤:
1、服务调用方通过ServiceLoader.load加载服务接口的实现类实例;
2、服务提供方实现服务接口后,在自己Jar包的META-INF/services目录下新建一个接口名全名的文件,并将具体实现类全名写入。
二、Spring SPI机制
很多开源框架库里都直接或间接使用了Java 的SPI机制。比如Spring就有类似的SPI机制,通过SpringFactoriesLoader代替JDK中ServiceLoader,通过META-INF/spring.factories文件代替META-INF/service目录下的描述文件,具体实现步骤不同,但原理都是使用Java 的反射机制。
public static <T> List<T> loadFactories(Class<T> factoryClass, @Nullable ClassLoader classLoader) {
Assert.notNull(factoryClass, "'factoryClass' must not be null");
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
List<String> factoryNames = loadFactoryNames(factoryClass, classLoaderToUse);
if (logger.isTraceEnabled()) {
logger.trace("Loaded [" + factoryClass.getName() + "] names: " + factoryNames);
}
List<T> result = new ArrayList<>(factoryNames.size());
for (String factoryName : factoryNames) {
result.add(instantiateFactory(factoryName, factoryClass, classLoaderToUse));
}
AnnotationAwareOrderComparator.sort(result);
return result;
}
spring boot读取properties文件spring.factories
三、Dubbo的SPI扩展
dubbo的扩展机制和java的SPI机制非常相似,但是又增加了如下功能:
1 可以方便的获取某一个想要的扩展实现,java的SPI机制就没有提供这样的功能
2 对于扩展实现IOC依赖注入功能:
举例来说:接口A,实现者A1、A2。接口B,实现者B1、B2。
现在实现者A1含有setB()方法,会自动注入一个接口B的实现者,此时注入B1还是B2呢?都不是,而是注入一个动态生成的接口B的实现者B$Adpative,该实现者能够根据参数的不同,自动引用B1或者B2来完成相应的功能
3 对扩展采用装饰器模式进行功能增强,类似AOP实现的功能
聊聊Java SPI机制的更多相关文章
- Java spi机制浅谈
最近看到公司的一些框架和之前看到的开源的一些框架的一些服务发现和接入都采用了java的spi机制. 所以简单的总结下java spi机制的思想. 我们系统里抽象的各个模块,往往有很多不同的实现方案,比 ...
- JDK源码解析之Java SPI机制
1. spi 是什么 SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件. 系统设计的各个抽象,往往 ...
- Java SPI机制实战详解及源码分析
背景介绍 提起SPI机制,可能很多人不太熟悉,它是由JDK直接提供的,全称为:Service Provider Interface.而在平时的使用过程中也很少遇到,但如果你阅读一些框架的源码时,会发现 ...
- 组件化框架设计之Java SPI机制(三)
阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 本篇文章将从深入理解java SPI机制来介绍组件化框架设计: ...
- Java SPI 机制实现解耦与本地化
SPI 是 Java 提供的一种服务加载方式,全名为 Service Provider Interface,可以避免在 Java 代码中写死服务的提供者,而是通过 SPI 服务加载机制进行服务的注册和 ...
- Java SPI机制详解
Java SPI机制详解 1.什么是SPI? SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制.SPI是一种动态替换发现的机制, 比如有个 ...
- java SPI机制
1. SPI是Service Provider Interfaces的简称.根据Java的SPI规范,我们可以定义一个服务接口,具体的实现由对应的实现者去提供,即Service Provider(服务 ...
- Java SPI机制学习笔记
最近在阅读框架源代码时,常常看到 SPI 的子包, 忍不住查了下: Service Provider Interface : 服务提供接口. JavaSPI 实际上是“基于接口的编程+策略模式+配置文 ...
- Java SPI机制简介
SPI 简介 SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制. 目前有不少框架用它来做服务的扩展发现, 简单来说,它就是一种动态替换发现 ...
随机推荐
- 快速掌握RabbitMQ(三)——消息确认、持久化、优先级的C#实现
1 消息确认 在一些场合,如转账.付费时每一条消息都必须保证成功的被处理.AMQP是金融级的消息队列协议,有很高的可靠性,这里介绍在使用RabbitMQ时怎么保证消息被成功处理的.消息确认可以分为两种 ...
- Codeforces Round #321 (Div. 2) E
终于补好了. 题目链接: http://codeforces.com/contest/580/problem/E E. Kefa and Watch time limit per test 1 sec ...
- 关于Properties 集 添加数据 遍历数据
public static void fun1(){ Properties v = new Properties(); v.setProperty("a","1" ...
- ubuntu16.04安装mysql5.7.15
1.在官网下载mysql安装包 直接选择第一个下载好了就行 2.进入你的下载文件夹下面 键入命令: tar -xvf mysql-server_5.7.13-1ubuntu16.04_i386.deb ...
- Maven自动部署(SCM-SVN/Git)(maven-scm-plugin/maven-release-plugin插件的使用)
以下内容引用自https://ayayui.gitbooks.io/tutorialspoint-maven/content/book/maven_deployment_automation.html ...
- 完整的MVC框架(前端、后台和数据库)
终于学完了数据库的连接,可以做一个完整的项目了,以前做的练习都没有关联到数据库,没法进行事务. MVC框架 先上图: 老师画的图,有点乱,但是大概意思还是可以理解. 这个练习是简单的存储一个学生读了哪 ...
- [转]c中按位分配int的方法
从网上看到这样一段c代码,让我发觉我的C基本功还是不行啊~~ typedef struct xp { int a:2; int b:2; unsigned int c:1; } xp; 不知道大家对i ...
- mongoVUE 破解方法
mongoVUE1.5.3的破解方法其实很简单 注册表中查找B1159E65-821C3-21C5-CE21-34A484D54444中的子项4FF78130 ,删除其下的三个子项即可. 开始-运行- ...
- <bgsound> - 背景音乐
摘要 项目 说明 形式 <bgsound src="..."> 支持 e2+ 标签省略 开始标签:必须,结束标签:无 ■ 说明 bgsound 是 background ...
- 【转载】C#扫盲之:==/Equals /ReferenceEquals 异同的总结,相等性你真的知道吗?
1.前言 == Equals ReferenceEquals 三个相等性测试,是.NET提供给程序员使用的三个方法,他们之间有什么联系和区别,你真的仔细研究过?虽然之前也多多少少知道一点,但是有时候又 ...