指定jdk_SPI面试必问:Dubbo和JDK的SPI究竟有何区别?

来源于公众号肥朝 ,

作者肥朝

前言

上一篇简单的介绍了spi的基本一些概念,但是其实Dubbo对jdk的spi进行了一些改进,具体改进了什么,来看看文档的描述

JDK 标准的 SPI 会一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但如果没用上也加载,会很浪费资源。

如果扩展点加载失败,连扩展点的名称都拿不到了。比如:JDK 标准的 ScriptEngine,通过 getName() 获取脚本类型的名称,但如果 RubyScriptEngine 因为所依赖的 jruby.jar 不存在,导致 RubyScriptEngine 类加载失败,这个失败原因被吃掉了,和 ruby 对应不起来,当用户执行 ruby 脚本时,会报不支持 ruby,而不是真正失败的原因。

增加了对扩展点 IoC 和 AOP 的支持,一个扩展点可以直接 setter 注入其它扩展点。

根据小学语文的阅读理解,不难概括出其实就是提高了性能和增加了功能.很多朋友都喜欢问,阅读源码不如从何下手,要准备些什么.如果只是粗略阅读源码,掌握大体思路,其实具备小学语文的阅读理解和看图写作业就差不多了(能看到本篇的均完全胜任这个条件,所以不要有任何恐惧心理).但是要领悟思想,对细节了如指掌,甚至写出更优秀的框架,那么就是四个字->终身学习.(比如现在关注肥朝公众号,一起交流讨论,终身学习即刻开启)

那dubbo这个改良后的spi究竟怎么提高性能,又增加了什么功能,那就是本篇要讲的.

b80297d16551738d463168fa91e0ee06.png

插播面试题

  • 既然你对spi有一定了解,那么Dubbo的spi和jdk的spi有区别吗?有的话,究竟有什么区别?
  • 你说你看过Dubbo源码,那你简单说下,他在设计上有哪些细节让你觉得很巧妙?(区分度高)

概念铺垫

Dubbo的拓展点机制涉及到众多的知识点,也是Dubbo中比较难的地方,和之前的集群容错有Cluster、Directory、Router、LoadBalance关键词一样,这个拓展点机制也有几个关键词,SPI、Adaptive、Activate.这些会陆续讲解,最后总结.

直入主题

提升性能

提升性能,我们最容易想到的方式是什么?其实这个和初高中政治答题一样,有万能公式的,那就是"缓存".所以面试无论问你什么(适用于Android,iOS,Web前端,Java等等…),只要和提升性能有关的,往缓存方向答肯定没错(当然按照"按点给分"的套路,往缓存方向答只是不至于让你拿0分,但是仅仅答缓存肯定拿不到满分).所以如果与jdk的spi对比,那么可以有以下几个点

1.从"万能公式"角度分析,增加缓存

因为部分朋友反馈说喜欢贴代码的形式,所以讲解在注释中

abc2a60d796657740a6e4e9d66247e4f.png

以下是缓存拓展点对象的

081d52b995499996943d488909d8d97b.png

为什么这个要单独拿出来说呢?很多朋友容易产生大意心理,以为缓存嘛,无非就是判断一下是否存在,不存在则添加.dubbo也不过如此.我不看源码也懂.但是你如果稍加注意,就会发现它在细节方面做得很好.

敲黑板划重点

在上一篇从Dubbo内核聊聊双亲委派机制中我就强调了,无论做什么,都要形成差异性.在Java中,最容易形成差异性的知识点,就是JVM和并发包.既然上一篇中我们提了JVM相关的内容(双亲委派机制),那么本篇我们就说说并发包的相关内容.我们仔细看上面的这段double-checked locking代码

f01125fb29ed3f83b4d58549fceb72c3.png

这里为什么用到了volatile关键字呢?看源码更重要的是看到这些细节,魔鬼都藏在细节当中!本来肥朝想展开讲一下这个volatile秀一波操作的,但是无奈篇幅有限,那个我给你个关键词.doubleCheck Singleton 重排序,你把这个关键词对着浏览器一搜.然后把搜索到的第一页结果都看完,你就知道这段代码并不是你想的只是判空加个缓存这么简单.他在并发细节上是有考虑的

2.从注解角度入手分析

既然是对比spi区别,并且dubbo中有@spi这个注解,那我们顺着注解看看能有什么线索.

如果在15年有用过dubbo,那么就会留意到@Extension这个注解,但是后来因为含义广泛废弃,换成了@SPI.

59f867224220bff5b3f60d7b8ed490e5.png

我们从上面这两部分代码和配置文件就不难分析出两点(如果对spi不熟悉的请先把上一篇spi(一)看一遍,基础不牢地动山摇的情况下没法分析)

  • JDK的spi要用for循环,然后if判断才能获取到指定的spi对象,dubbo用指定的key就可以获取
1//返回指定名字的扩展2public T getExtension(String name){}
  • JDK的spi不支持默认值,dubbo增加了默认值的设计
1//@SPI("javassist")代表默认的spi对象,比如Compiler默认使用的是javassist,可通过2ExtensionLoader loader = ExtensionLoader.getExtensionLoader(Compiler.class);3compiler = loader.getDefaultExtension();4//方式获取实现类,根据配置,即为5//com.alibaba.dubbo.common.compiler.support.JavassistCompiler

增加功能

增加的功能,就如文档所说的,spi增加了IoC、AOP

AOP这是个老生常谈的话题了,谈到AOP大家最容易联想到Spring,甚至因为AOP常用在事务的场景,甚至就有不少人认为AOP就是事务.所以肥朝建议初学者学习AOP的路线大致如下:

1// 这一步步演进的过程,才是最大的收获2装饰者设计模式->静态代理->JDK、cglib、Javassist优缺点对比->AOP源码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值