• dubbo源码分析3——SPI机制中的ExtensionLoader类的objectFactory属性分析


    ExtensionLoader类是整个SPI的核心类,每个SPI都会对应一个ExtensionLoader类实例,这个类的构造方法如下:

    private ExtensionLoader(Class<?> type) {
            this.type = type;
            objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
        }

     里面的objectFactory对应的就是ExtensionFactory类的实例,通过源码能发现,ExtensionFactory自身也是一个SPI接口,那么它也会有一个对应的ExtensionLoader类实例,这个类实例中的objectFactory属性为null ,而其他的ExtensionLoader类实例中的 objectFactory属性是 : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()

    我们就先来分析下ExtensionLoader.getExtensionLoader(ExtensionFactory.class) 这句代码。

    // 先通过type从缓存中获取ExtensionLoader,如果缓存中不存在,则创建相应的ExtensionLoader放入缓存,再返回
    public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) { if (type == null) throw new IllegalArgumentException("Extension type == null"); if(!type.isInterface()) { throw new IllegalArgumentException("Extension type(" + type + ") is not interface!"); } if(!withExtensionAnnotation(type)) { throw new IllegalArgumentException("Extension type(" + type + ") is not extension, because WITHOUT @" + SPI.class.getSimpleName() + " Annotation!"); } ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type); if (loader == null) { EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type)); loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type); } return loader; }

    getAdaptiveExtension()内部的调用过程如下(注意这是一个实例方法):

    -> if(cachedAdaptiveInstance.get() == null){ createAdaptiveExtension() }

          ->getAdaptiveExtensionClass()   //下面的调用有两个分支

                  // 分支1
        ->getExtensionClasses()
          ->loadExtensionClasses()
            ->loadFile(extensionClasses, DUBBO_INTERNAL_DIRECTORY);

            injectExtension   //完成注入,这是 ExtensionFactory 类的作用之所在 

                   // 分支2

                   ->createAdaptiveExtensionClass()

                      injectExtension 

    经过上述分析,可以得出 ExtensionLoader.getExtensionLoader(ExtensionFactory.class) 返回的是 com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory类的实例,这个类在ExtensionFactory的SPI描述文件中的第二行

    spring=com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory
    adaptive=com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory
    spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory

     AdaptiveExtensionFactory的源码如下

    @Adaptive
    public class AdaptiveExtensionFactory implements ExtensionFactory {
        
        private final List<ExtensionFactory> factories;
        
        public AdaptiveExtensionFactory() {
            ExtensionLoader<ExtensionFactory> loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class);
            List<ExtensionFactory> list = new ArrayList<ExtensionFactory>();
            for (String name : loader.getSupportedExtensions()) {
                list.add(loader.getExtension(name));
            }
            factories = Collections.unmodifiableList(list);
        }
    
        public <T> T getExtension(Class<T> type, String name) {
            for (ExtensionFactory factory : factories) {
                T extension = factory.getExtension(type, name);
                if (extension != null) {
                    return extension;
                }
            }
            return null;
        }
    
    }

     总结:

             通过上述分析,可以知道:

             1. 除了ExtensionFactory之外,其他的SPI接口对应的ExtensionLoader类实例中的 objectFactory属性都是AdaptiveExtensionFactory的实例对象。

             2.  且这些AdaptiveExtensionFaatory实例都是同一个,这是因为ExtensionLoader的类属性会会在EXTENSION_LOADERS中缓存创建好的loader,每个loader又会在其的实例属性cachedAdaptiveClass缓存这个adaptive性质的Extension类。

             3.  ExtensionLoader的injectExtension方法完成的注入工作正是objectFactory(ExtensionFactory类)的真正作用。这个作用留待下一篇再做分析。 

  • 相关阅读:
    Qt之课外实践——文件操作(简单清道夫)
    【转载】2018 hosts 持续更新访问 gu歌【更新于:2018-05-03】
    NBU基本常用命令
    运维的四个发展阶段,看看自己在哪个阶段,聊聊怎么升级打怪
    云笔记使用心得分享
    LNMP一键安装包
    expect脚本中,变量的写法
    VERITAS NETBACKUP运维手册(工作总结)
    善用良器:帮你有效管理时间的7种工具
    RAID0 1 5 10原理、种类及性能优缺点对比
  • 原文地址:https://www.cnblogs.com/hzhuxin/p/7543990.html
Copyright © 2020-2023  润新知