dubbo扩展点加载器,用于加载用@SPI修饰的接口

 

 

提供对外静态方法:

ExtensionLoader<T> getExtensionLoader(Class<T> type)

 

dubbo LeastActiveLoadBalance 原理_扩展名

 


 

EXTENSION_LOADERS缓存已有扩展点加载器,这种模式可用于当程序启动后便不再修改更新的配置,当多线程同时进入if中,不会出现ExtensionLoder被更新问题,线程安全

若当前类型不存在缓存中,新建一个ExtensionLoader,构造方法被私有化,并存入缓存

 

dubbo LeastActiveLoadBalance 原理_扩展名_02

 


构造方法中记录当前指定类对象,若指定类不是ExtensionFactory,则获取ExtensionFactory的ExtensionLoader并调用其getAdaptiveExtension方法


cachedAdaptiveInstance属于Holder,这种模式优势在于每个对象中实现单例,其中采用双重判空保证线程安全,实质调用createAdaptiveExtension方法,若创建可适配扩展点异常,记录异常,再次调用不再尝试创建

 

dubbo LeastActiveLoadBalance 原理_构造方法_03

 


 

先获取可适配扩展类对象,而后初始化构造对象,injectExtension从ExtensionFactory中获取对象注入到先前新建的对象中;ExtensionFactory等同扩展对象的管理容器,

 

dubbo LeastActiveLoadBalance 原理_类对象_04

 


 

getExtensionClasses方法获取所有扩展Class,只在初始化时做一次,如果cachedAdaptiveClass为null,调用createAdaptiveExtensionClass方法

dubbo LeastActiveLoadBalance 原理_类对象_05

 


调用LoadExtensionClasses()

dubbo LeastActiveLoadBalance 原理_扩展名_06

 

从@SPI注解中获取配置的默认扩展点名称,只能配置一个默认扩展名,调用LoadFile方法读取如下路径META-INF/services/   META-INF/dubbo/  META-INF/dubbo/ internal/

 

dubbo LeastActiveLoadBalance 原理_构造方法_07

 

 


 

文件名与类名一致,以UTF-8方式读取文件,而后解析key=value形式,value指定类名,若该类实现自type接口,继续做实现类上注解处理

 

 

dubbo LeastActiveLoadBalance 原理_类对象_08

 


@Adaptive注解不必做wrapper,直接赋值cachedAdaptiveClass

 

dubbo LeastActiveLoadBalance 原理_扩展名_09

 


若指定类有以指定类型type为参数的构造方法,则将其添加到集合cachedWrapperClasses中

 

dubbo LeastActiveLoadBalance 原理_构造方法_10

 


若只存在空构造方法,若配置中未指定key(即name未指定)取@Extension指定name作为扩展名

 

dubbo LeastActiveLoadBalance 原理_扩展名_11

 


name可配置多个,若同一个扩展名对应多个class将会抛出异常;若实现类包含@Active注解,则将扩展名与active注解关联

 

 

既然已经读取加载了file中指定的所有扩展类,让我们回到createAdaptiveExtensionClass()方法,创建扩展类对象

 

dubbo LeastActiveLoadBalance 原理_扩展名_12

 


 

为存在@Adaptive注解修饰的方法生成扩展类,若无此方法无需配置

 


如何取得Extension中所有符合条件的实例?

dubbo LeastActiveLoadBalance 原理_构造方法_13

 


遍历当前ExtensionLoaderListener中cachedActivates字典,若满足@Active注解配置value为空或者url中含有该参数则加入到返回集合中,value配置多个时只需要有一个满足即可