dubbo理解(四)
本质是解决同一个接口,有多种实现时,使用者如何能够方便选择实现的问题。
JDK中的SPI如何配置使用的:
Jdk中,选择SpiService的实现方法在jar中放置一个META-INF/services目录,目录中存放一个文本文件(文件名是SpiService接口的全路径名),文本中列入你选择的实现类(一行放一个,是实现类的全路径名)
有了上述配置,在java程序中,使用
ServiceLoader.load(SpiService.class)
,即可将配置中选择的实现类,实例化并放入一个集合中,供我们使用,如下图:
dubbo的SPI -----比jdk的选择方案,要牛叉一点
与jdk相比,dubbo将选择权下放到了配置文件中(你配置谁,它为你实例化谁)dubbo的目标,以上图cluster为例,failsafe/failover/failfast都是cluster的一种实现,现在我们可以在标签配置时,方便地进行选择
dubbo中的api的使用流程
1)凡是dubbo中,接口上有@SPI标注的,都表明此接口支持扩展,如下图:
2)单独建立jar工程,引入dubbo依赖(注意依赖scope设为provided)
3)在工程中,为要扩展的接口,编写实现类
4)在资源文件中,为每个实现类,定义分配一个key
5)在消费端,便可使用上面步骤中国定的实现策略(以key指代)
dubbo的SPI实现原理----解读其核心ExtensionLoader
1)看源码疑云:
疑问:dubbo中reference使用的protocol ----是静态类变量,而ReferenceConfig(ReferenceBean的父级类)是每个标签一个实例对象(每个对象配置的protocol是不同的)
此时protocol的对应一定出问题。
2)ExtensionLoader的加载步骤:
2.1 getExtensionLoader(Protocol.class)为protocol接口生成一个加载器2.2 getAdaptiveExtension()使用加载器生成一个代理对象 ----protocol接口对象
2.3 代理对象执行时,根据参数(扩展名 extName)选择时机对象 ----
2.4 最后的效果:每个接口扩展点 —对应一个ExtensionLoader加载器,如: protocol -------ExtensionLoader实例<protocol>
filter ------ExtensionLoader实例<filter>
loadbalance -------ExtensionLoader实例<loadbalance>
2.5 代理类的逻辑
代理类的创建,是通过动态代码,生成一个类源码,然后经过编译得到代理类的class,如上图。代理类生成源码的逻辑,只生成接口中标注了@Adaptive的方法,如下:
3)dubbo的SPI整体执行逻辑
a、dubbo启动加载实现类时,以 key实例 方式map缓存各个实现类b、实际调用时,通过key–取实现(需要的那个实现)
c、调用的发生,由生成的代理对象来发起,最终是从URL总线中,找出extName值,extName做为key,在缓存map中取出正确的实现类
以上是 dubbo理解(四) 的全部内容, 来源链接: utcz.com/z/518958.html