dubbo中的ExtensionLoader

dubbo中自己实现了一套SPI,解决了dubbo的可扩展性问题,方便了框架的各层可以在多个不同的实现之间进行来回切换。

SPI的实现主要在类ExtensionLoader中,这个类的构造函数接收一个Class类型的参数,并且这个class必须是接口,必须用注解spi进行标注。有多少个可扩展接口,就有多少个ExtensionLoader的实例。

这个类中一共有三类方法:根据名字获取实现、获取某个接口的适配实现和获取某个接口的激活实现

1、根据名字获取实现

这类方法比较好理解,如下Protocol有下面这么多的实现:



 

等号前面的是名字,等号后面的是实现,例如:如果传入dubbo就会返回DubboProtocol

下面对这个方法的源码进行分析



 

这个方法比较好理解,其实就是判断缓存,如果有直接返回,没有的话通过createExtension方法进行创建



 

第499行调用getExtensionClasses(),会返回这个接口的所有实现,这个方法的内部会有扫描三个目录进行初始化的过程。

第509行的injectExtension方法的主要作用是对获取到的这个实现的内部的属性字段进行赋值。就是如果这个类中有的字段的类型是SPI接口或者在spring容器中可以找到对应的ben,那么就对这些字段进行赋值。

第510到515行是对当前返回的实例进行再次包装,当然是如果这个spi接口的实现有包装类的话。如果某个实现类,有单个参数的构造函数,并且参数类型是当前SPI接口,那么这个类就是包装类。他就好对当前

要返回的类,进行包装,有可能存在多个包装器类。例如上面第一张截图中的ProtocolFilterWrapper和ProtocolListenerWrapper就是两个包装器类

总结一下:

(1)初始化当前spi接口的所有实现(会扫描三个目录)到内存中

(2)根据名字返回对应的实现的实例

(3)对这个实例进行属性字段的赋值,来源于其他的spi实现或者spring容器

(4)如果当前spi接口有包装器类,对当前实现进行包装,有可能有多个包装器类

这类方法基本是不会被外面的类调用,主要是为另外两类方法服务

2、获取SPI接口的适配实现,只会返回一个实现类。

这个方法要@Adaptive注解配合实现。这个注解可以标注在类上,也可以标注在方法上,如果是标注在方法上只能是接口方法不是类方法。

(1)如果某个SPI接口的实现类,被这个注解进行了标注,那么直接返回这个实现类

(2)如果接口的方法被这个注解进行了标注,那么会利用字节码进行动态生成一个类。

如果接口像下面这么标注



 



 

那么动态生成的方法将会是下面这样



 



 

 由于某个SPI接口的适配实现只会有一个,所有(1)的优先级大于(2),获取适配实现主要是解决,只有在程序运行期间才能却能使用哪个实现

3、获取SPI接口的激活实现,可以是多个

最常见的例子就是获取Filter

激活某个实现有两种方式

(1)使用注解Activate进行标注,这个注解有两个重要的参数一个是group,一个是value。这两个参数都是数组

group表示getActivateExtension方法传入的grop值如果被注解上的group数组包含,那么返回这个扩展。

value表示URL的parameter参数中,如果有一个参数的key和value数组的任何一个元素相同,那么返回这个扩展。

group和value不知道,表示不做约束,无条件激活这个实现

(2)不通过注解标注还可以在URL参数中指定实现类的名字,这个方法既可以激活某个实现,也可以去掉(1)中已经激活的实现,例如下面这个配置filter的例子



 

总结一下:

(1)通过注解进行标注的实现,被称为缺省扩展,包括dubbo自带的(入各种filter)和用户自定义的扩展用注解进行了标注。

(2)通过url的参数来指定实现的名字,也可以激活某个或某些实现。

(3)url的参数也可以去掉缺省扩展,规则见上面的图。

下面分析下代码:



 

第196行表示没有去掉全部的缺省扩展

198行变量所有的通过注解进行标注的实现

201行grop可以匹配上

203、204、205判断这个缺省扩展没有通过URL的参数去掉,isActivate判断注解的value值中任意一个元素和RUL参数的任意一个key相同

206表示此扩展被激活了,添加到list中

210排序



 

上面这部分代码,就是在url参数中指定扩展名字是的处理逻辑

215、216行表示没有在url参数中排除这个扩展

217就是处理和缺省扩展的排序关系

猜你喜欢

转载自lalahei.iteye.com/blog/2407532