SPI 机制-插件化扩展功能
SPI(Service Provider Interfaces),中文直译服务提供者接口,一种服务发现机制。可能很多人都不太熟悉这个机制,但是平常或多或少都用到了这个机制,比如我们使用 JDBC 连接操作数据库的时候。
SPI 主要适用于功能扩展的场景,如一些框架提供某一部分功能可以由第三方开发人员扩展,满足其自身业务需求。
假设我们在公司内实现了一个统一登陆框架,框架内部仅仅提供用户名/密码登陆方式。后来 A 部门想使用该框架,但是他们想增加微信登陆授权。正常情况下,我们可以改动登陆框架代码,增加微信登陆实现方式。如果后面又增加 QQ 登陆,淘宝登陆那?也只能不断相应的实现。
SPI 实现方式
这种情况如果使用 SPI,可以在不用改动框架代码前提下,增加新的登陆实现方式。下面用代码演示如何使用 SPI。
定义接口
首先我们新建一个 maven 项目 oauth-api
,在这个项目创建一个公共接口。
public interface OauthLoginService {void login();
}
第三方实现该接口
再新建一个 maven 项目 wechat-oauth
,引入上面 oauth-api
依赖
public class WechatLoginService implements OauthLoginService {@Overridepublic void login() {System.out.println("使用微信登陆授权");}
}
定义配置文件
SPI 需要将接口实现定义在配置文件中,文件名为接口全名称,如 com.andyxh.OauthLoginService
,配置文件需放在 resources\META-INF\services 文件夹下。文件内容如下:
com.another.WechatLoginService
加载接口实现类
新建 maven 项目 oauth-login
,在这个项目中引入 wechat-oauth
与 oauth-api
依赖。SPI 核心将会使用 java.util.ServiceLoader
读取上面上面定义配置文件,加载所有服务实现类。使用代码如下:
ServiceLoader<OauthLoginService> serviceLoader=ServiceLoader.load(OauthLoginService.class);
serviceLoader.forEach(OauthLoginService::login);
打印结果:
使用微信登陆授权
SPI 实际应用
上面说过 JDBC 中使用到 SPI 进制。 JDK 定义标准数据库接口,相应的数据库厂商实现这类接口。以 mysql-connector-javal
为例。
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency>
mysql jar 包 META-INF/services 中存在java.sql.Driver
文件,这个文件定义了实现类。
com.mysql.cj.jdbc.Driver
可以看到 java.sql.Driver
是标准 SPI 接口,而 com.mysql.cj.jdbc.Driver
是 mysql 标准实现接口。
何时加载 java.sql.Driver
?
我们将会使用 DriverManager.getConnection
获取相应数据库连接。这个类内部存在一个静态代码块,将会使用 ServiceLoader
加载实现类。
static {loadInitialDrivers();println("JDBC DriverManager initialized");}private static void loadInitialDrivers() {....ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class); Iterator<Driver> driversIterator = loadedDrivers.iterator(); try{ while(driversIterator.hasNext()) { driversIterator.next(); } } catch(Throwable t) { // Do nothing } return null; }....}
Java SPI 存在问题
ServiceLoader
一次性将会实例化所有实现,但是如果没有某一扩展初始化耗时很久,但是却不需要立刻使用,就会非常浪费资源。
基于这个问题, Dubbo SPI 机制改进 Java SPI 的不足,做到按需加载并且增加 ioc 与 aop 的功能,下篇文章可以在具体聊聊,敬请期待。
SPI 机制-插件化扩展功能相关推荐
- Java SPI机制实现插件化扩展功能
Java SPI机制实现插件化扩展功能 1.背景 我们有一个图数据库的服务,用户希望在不修改现有源代码的情况下扩展自定义的分词器,达到可插件式扩展功能的目标. 通过Java的SPI机制实现插件式的扩展 ...
- Java SPI实现插件化
SPI 机制使用到很经典的设计原则,在学习之前,首先了解一下: 开闭原则:面向拓展开放,对修改关闭: 里氏替换原则:父类出现的地方都应该可以让子类替换,让子类去增强和扩展功能: 依赖倒置原则:面向接口 ...
- 【java】SPI机制详解
1.概述 以前的文章:[SPI]java基础之SPI框架实现 转载:Java常用机制 - SPI机制详解 PI(Service Provider Interface),是JDK内置的一种 服务提供发现 ...
- Android 插件化原理入门笔记
Android开发笔记 onGithub 笔记,参考7.2中所列参考文章所写,DEMO地址在PluginTestDemoApplication 1.综述 2015年是Android插件化技术突飞猛进的 ...
- c++插件化 NDD源码的插件机制实现解析
插件机制是一种框架,允许开发人员简单地在应用程序中添加或扩展功能.它使广泛使用,因为它可以作为模块被重复使用,并使它们更易于维护和扩展,因此它们在应用程序中非常有用.插件机制允许管理员在需要时轻松安装 ...
- Android 插件化原理学习 —— Hook 机制之动态代理
前言 为了实现 App 的快速迭代更新,基于 H5 Hybrid 的解决方案有很多,由于 webview 本身的性能问题,也随之出现了很多基于 JS 引擎实现的原生渲染的方案,例如 React Nat ...
- 平安保险基于 SPI 机制的 RocketMQ 定制化应用
作者:孙园园|平安人寿资深开发 为什么选用 RocketMQ 首先跟大家聊聊我们为什么会选用 RocketMQ,在做技术选型的过程中,应用场景应该是最先考虑清楚的,只有确定好了应用场景在做技术选型的过 ...
- Android插件化原理解析——Hook机制之动态代理
使用代理机制进行API Hook进而达到方法增强是框架的常用手段,比如J2EE框架Spring通过动态代理优雅地实现了AOP编程,极大地提升了Web开发效率:同样,插件框架也广泛使用了代理机制来增强系 ...
- Android 插件化原理解析——Hook机制之AMSPMS
在前面的文章中我们介绍了DroidPlugin的Hook机制,也就是代理方式和Binder Hook:插件框架通过AOP实现了插件使用和开发的透明性.在讲述DroidPlugin如何实现四大组件的插件 ...
- android handler的机制和原理_Android 插件化原理——Hook机制之AMSamp;PMS解析
在前面的文章中我们介绍了DroidPlugin的Hook机制,也就是代理方式和Binder Hook:插件框架通过AOP实现了插件使用和开发的透明性.在讲述DroidPlugin如何实现四大组件的插件 ...
最新文章
- Linux Wi-Fi 编程API介绍
- 【c语言】输入一个4位数,求四位数中各位数相加之和
- 大多数的自动驾驶公司,注定要倒闭
- PyCharm去掉满屏的波浪线
- CFileDialog 在使用sdk 后出现异常 Access violation
- 博途pcpg接口无法选择_博途TIA功能,如何创建一个S7-1200的项目及硬件组态?
- 沙漠种水稻,88岁的袁隆平又创造奇迹!他参与的“袁米”还有个大计划
- java调用MySQL脚本_Java调用SQL脚本执行常用的方法示例
- 小鹏N5申报图曝光 搭载155KW电机、NEDC 600公里与P5相同
- 游戏社交不足怎么办? 游戏发行中的社交化运营经验分享
- paip.跟踪DISCUZ积分日志功能总结
- UML入门以及Plant UML工具介绍
- 哈尔·埃尔罗德《早起的奇迹》读书笔记
- 【Pyecharts50例】一个Tab下添加多个图表/tab.add()
- 狗和猫有相同的情绪反应吗?
- mongo查询时区转换
- windows bat
- 马斯克宣布重磅消息!一切来得那么快!
- 500天后是几几年几月几日
- 记录2015年年初跳槽的经历!