dubbo扩展点加载器,用于加载用@SPI修饰的接口
提供对外静态方法:
ExtensionLoader<T> getExtensionLoader(Class<T> type)

EXTENSION_LOADERS缓存已有扩展点加载器,这种模式可用于当程序启动后便不再修改更新的配置,当多线程同时进入if中,不会出现ExtensionLoder被更新问题,线程安全
若当前类型不存在缓存中,新建一个ExtensionLoader,构造方法被私有化,并存入缓存

构造方法中记录当前指定类对象,若指定类不是ExtensionFactory,则获取ExtensionFactory的ExtensionLoader并调用其getAdaptiveExtension方法
cachedAdaptiveInstance属于Holder,这种模式优势在于每个对象中实现单例,其中采用双重判空保证线程安全,实质调用createAdaptiveExtension方法,若创建可适配扩展点异常,记录异常,再次调用不再尝试创建

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

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

调用LoadExtensionClasses()![技术分享图片]()

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

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

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

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

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

name可配置多个,若同一个扩展名对应多个class将会抛出异常;若实现类包含@Active注解,则将扩展名与active注解关联
既然已经读取加载了file中指定的所有扩展类,让我们回到createAdaptiveExtensionClass()方法,创建扩展类对象

为存在@Adaptive注解修饰的方法生成扩展类,若无此方法无需配置
如何取得Extension中所有符合条件的实例?

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