内容简介:JDK原生用法
首先我们了解下何为SPI,SPI全称: Service Provider Interface,由一方提供接口规范,另一方负责具体实现。 其理念跟软件 设计模式 中的策略模式有点类似 ,前者是业务 架构设计维度 ,后者是 接口编程维度 。
SPI优势: 有效解决了代码高耦合问题,避免使用大量的if else 嵌套逻辑,大大提高了系统的可维护性和扩展性。对于复杂的业务场景,可以实现系统间的解耦,通过Restful接口完成交互,又避免了不同的商户接入带来的重复开发工作。
JDK原生用法
通过规则约定加规范的方式,按照接口名称定义配置文件,并将处理不同业务逻辑的实例类添加到配置文件中,通过类加载器完成加载。
/**
* 创建订单接口
* @author onlyone
*/
public interface OrderService {
String createOrder(AddOrderParam addOrderParam);
}
然后在 “ META-INF/services ”路径下创建文件 “com.boot.service.OrderService”, 文件内容为:
com.boot.service.impl.TaobaoOrderService
com.boot.service.impl.TianmaoOrderService
最后借助jdk原生的 ServiceLoader 去META-INF/services目录下加载配置文件并将类实例化,完成调用。
代码示例:
https://github.com/aalansehaiyang/spi-example
Dubbo 框架用法
jdk原生框架采用全部加载机制,不管需不需要。导致系统初始启动时会占用大量系统资源,耗时较长。dubbo对其进行改造,重写加载机制,采用按需加载。
-
自定义注解 @SPI
-
重写加载类 ExtensionLoader
-
并大量使用缓存,提升性能
-
提供 getExtension 方法,可以 获取具体实现类
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
....各种校验
} else {
//缓存中获取扩展加载器,为空则进行新建
ExtensionLoader<T> loader = (ExtensionLoader)EXTENSION_LOADERS.get(type);
if (loader == null) {
EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader(type));
loader = (ExtensionLoader)EXTENSION_LOADERS.get(type);
}
return loader;
}
}
public T getExtension(String name) {
。。。参数校验
Holder<Object> holder = cachedInstances.get(name); //从缓存中获取持有者
if (holder == null) { //如果为空,创建一个持有者
cachedInstances.putIfAbsent(name, new Holder<Object>());
holder = cachedInstances.get(name);
}
Object instance = holder.get(); //从持有者获取实现类
if (instance == null) { //如果为空
synchronized (holder) {
instance = holder.get();
//双重判空检查
if (instance == null) {
//采用懒加载模式加载实现类
instance = createExtension(name);
holder.set(instance);
}
}
}
return (T) instance;
}
架构衍生
随着一个企业越做越大,沉淀了很多数据,会通过API开放形式接入网关,给外部的ISV提供原始数据服务,进一步打造业务生态圈。 但是这种模式有个缺点,规范和实现由内部控制,外部单向依赖。
如果某些业务场景需要双向依赖,可以考虑使用SPI模式, 由平台方定义接口规范,第三方来实现内部逻辑,通过HTTP协议来调用。可以理解成 SPI是传统API的反向调用 。
存在这样一种业务场景,平台需要向开发者请求数据信息 。比如一些大电商卖家都有自己的仓库,本地库存系统,自己的售卖网站,同时也在淘宝、京东、拼多多等三方平台售卖商品,如果想共享一套库存数据要怎么设计,可以考虑SPI。
图引自程序架道
首先平台方定义业务场景,并在场景下定义SPI接口规范,接入方按规范实现接口逻辑(比如:调用本地数据库判断是否有库存),并将API服务注册到网关。 当用户访问平台系统时,会根据访问的店铺、IP地址、用户数据等信息, 路由寻址 到指定的商户系统,完成数据交互,并进行后续业务流程 。
当然,不同公司的技术实力参差不齐,系统稳定性、接口响应速度都不一样,平台系统的容错能力、超时机制要深入建设,避免局部慢请求,引发雪崩效应。
小结:
-
提供了内部数据的开放能力,借助ISV的开发能力,形成一个大的业务生态圈
-
外部系统数据可以以插件的形式注册到平台,由平台指定统一规范和路由能力,
满足更复杂的业务诉求。
往期推荐
获取方式:点“ 在看 ”,关注公众号并回复 架构 领取,更多内容陆续奉上。
以上所述就是小编给大家介绍的《借助 SPI 解决复杂业务扩展问题》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 借助 SPI 解决复杂业务扩展问题
- 如何借助 Proxy 代理,提升架构扩展性
- 借助北斗导航可以远程放羊
- 借助Spark调度MPI作业
- 借助 Swift 的枚举来简化登录
- 如何借助Molecule测试Ansible角色
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Effective JavaScript
David Herman / Addison-Wesley Professional / 2012-12-6 / USD 39.99
"It's uncommon to have a programming language wonk who can speak in such comfortable and friendly language as David does. His walk through the syntax and semantics of JavaScript is both charming and h......一起来看看 《Effective JavaScript》 这本书的介绍吧!