dubbo扩展点加载器,用于加载用@SPI修饰的接口
提供对外静态方法:
ExtensionLoader<T> getExtensionLoader(Class<T> type)
![技术分享图片](https://image.cha138.com/20210702/8d0b422b4f5148cbb9931023302e3087.jpg)
EXTENSION_LOADERS缓存已有扩展点加载器,这种模式可用于当程序启动后便不再修改更新的配置,当多线程同时进入if中,不会出现ExtensionLoder被更新问题,线程安全
若当前类型不存在缓存中,新建一个ExtensionLoader,构造方法被私有化,并存入缓存
![技术分享图片](https://image.cha138.com/20210702/bb1bf0fbe16a408bba47f5893b7bf770.jpg)
构造方法中记录当前指定类对象,若指定类不是ExtensionFactory,则获取ExtensionFactory的ExtensionLoader并调用其getAdaptiveExtension方法
cachedAdaptiveInstance属于Holder,这种模式优势在于每个对象中实现单例,其中采用双重判空保证线程安全,实质调用createAdaptiveExtension方法,若创建可适配扩展点异常,记录异常,再次调用不再尝试创建
![技术分享图片](https://image.cha138.com/20210702/00b7c7afc39544c4a88a653799571d26.jpg)
先获取可适配扩展类对象,而后初始化构造对象,injectExtension从ExtensionFactory中获取对象注入到先前新建的对象中;ExtensionFactory等同扩展对象的管理容器,
![技术分享图片](https://image.cha138.com/20210702/9cb9cf59120b4250a7cc464d92e72994.jpg)
getExtensionClasses方法获取所有扩展Class,只在初始化时做一次,如果cachedAdaptiveClass为null,调用createAdaptiveExtensionClass方法
![技术分享图片](https://image.cha138.com/20210702/907954ab8fbc4163809ed9327fbcb578.jpg)
调用LoadExtensionClasses()![技术分享图片]()
![技术分享图片](https://image.cha138.com/20210702/d58a02affd7a41b9a8ad4a08151a2f3c.jpg)
从@SPI注解中获取配置的默认扩展点名称,只能配置一个默认扩展名,调用LoadFile方法读取如下路径META-INF/services/ META-INF/dubbo/ META-INF/dubbo/ internal/
![技术分享图片](https://image.cha138.com/20210702/d8a5cf60a96e420a813ceb29067ff31f.jpg)
文件名与类名一致,以UTF-8方式读取文件,而后解析key=value形式,value指定类名,若该类实现自type接口,继续做实现类上注解处理
![技术分享图片](https://image.cha138.com/20210702/5614217952344ca8bf39d07d04d3a2a4.jpg)
@Adaptive注解不必做wrapper,直接赋值cachedAdaptiveClass
![技术分享图片](https://image.cha138.com/20210702/887de2fe2db64f94abceb12f93dfa7eb.jpg)
若指定类有以指定类型type为参数的构造方法,则将其添加到集合cachedWrapperClasses中
![技术分享图片](https://image.cha138.com/20210702/f71058d52295465eb1ed0d87fa0087e7.jpg)
若只存在空构造方法,若配置中未指定key(即name未指定)取@Extension指定name作为扩展名
![技术分享图片](https://image.cha138.com/20210702/d5403b116059484686da32424157811f.jpg)
name可配置多个,若同一个扩展名对应多个class将会抛出异常;若实现类包含@Active注解,则将扩展名与active注解关联
既然已经读取加载了file中指定的所有扩展类,让我们回到createAdaptiveExtensionClass()方法,创建扩展类对象
![技术分享图片](https://image.cha138.com/20210702/7f678ec2125a45039960f0dc2ec2561a.jpg)
为存在@Adaptive注解修饰的方法生成扩展类,若无此方法无需配置
如何取得Extension中所有符合条件的实例?
![技术分享图片](https://image.cha138.com/20210702/dc0a4c4638fe4c5d9401553c669cf7b4.jpg)
遍历当前ExtensionLoaderListener中cachedActivates字典,若满足@Active注解配置value为空或者url中含有该参数则加入到返回集合中,value配置多个时只需要有一个满足即可