概述
spi是什么?
SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的接口,它可以用来启用框架扩展和替换组件。 SPI的作用就是为这些被扩展的API寻找服务实现。
使用场景
调用者根据实际使用需要,启用、扩展、或者替换框架的实现策略,如下使用场景
1.JDBC加载不同类型数据库的驱动
2.slf4j需要替换不同日志组件
java 的spi
ServiceLoader<ISayHello>
serviceLoader=ServiceLoader.load(ISayHello.class);
System.out.println("Java SPI");
serviceLoader.forEach(ISayHello::say);
核心逻辑:
从上图可以看出,核心逻辑就是使用stack特性完成迭代,先把加载所有类入stack,然后调用next时候一个出栈,直到空为止则遍历完成
主要的核心对象有:
ServiceLoader:服务加载器,spi核心入口类,加载在指定的类型而且在配置文件当中配置的类,并且实例化(实例交给LayerLookupIterator迭代器做)。
LayerLookupIterator:翻译过来,懒加载迭代器,ServiceLoader内置的默认是实现的迭代器。从源码分析得处,就是在调用LayerLookupIterator对服务进行遍历时候会装载配置文件类,并且实例化。
Java SPI 不足之处:
1.虽然java spi是懒加载形式,但是获取某种实例的时候,是通过迭代器形式获取,所以依然加载所有配置文件中的所有实现类的实例。
2.不能按需加载。Java SPI在加载扩展点的时候,会一次性加载所有可用的扩展点,很多是不需要的,会浪费系统资源。
3.获取某个实现类的方式不够灵活,只能通过 Iterator 形式获取,不能根据某种类型(策略标识)来获取对应的实现类。
dubbo 的spi
讲完Java SPI的不足,那么dubbo 的spi肯定有他的优点之处,不然不可能费那么大的劲重复造轮子。
相比Java的spi,dubbo做了以下改进:
1.开闭原则,dubbo预制好很多spi地方,无需进行源码修改即可进行拓展。(这个不算改进)
2.延时加载,按需加载,可以一次性只加载自己所需要的实现。(大大改进)
3.增加对IOC容器的支持和AOP的支持,简单说就是支持Spring最强功能,可以将dubbo的spi实例注入到其他bean
dubbo的spi是如何实现按需加载?
其实原理很简单,就是在配置文件做了手脚,如下
因为做了key和value的配置映射,就可以对实现类进行分类。获取的实现类代码如下。
ExtensionLoader<ISayHello> extensionLoader =
ExtensionLoader.getExtensionLoader(ISayHello.class);
ISayHello optimusPrime = extensionLoader.getExtension("jason");
optimusPrime.say();
ISayHello bumblebee = extensionLoader.getExtension("jerry");
bumblebee.say();
总结:
1.java的spi和dubbo的spi都是给开发者需要对源码进行二次开发或者二次拓展进行预留一些口子,符合代码的开闭原则。
2.dubbo的spi对java的spi进行的一些适当改进,可以按需加载,同时增加对spring容器的一些支持,这样方便类似spring全家桶开发代码极大方便。
3.两者实现原理都很简单,dubbo的按需加载从本质上来讲对实现类进行二级分类,从更小级别按需加载。
参考:
Java SPI 与 Dubbo SPI 有什么区别?
面试大咖说:Dubbo SPI 和 Java SPI 区别
最后
以上就是醉熏时光为你收集整理的dubbo spi和java spi的原理和区别的全部内容,希望文章能够帮你解决dubbo spi和java spi的原理和区别所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复