聊聊Dubbo - Dubbo可扩展机制源码解析

Dubbo可扩展机制实战中,咱们了解了Dubbo扩展机制的一些概念,初探了Dubbo中LoadBalance的实现,并本身实现了一个LoadBalance。是否是以为Dubbo的扩展机制很不错呀,接下来,咱们就深刻Dubbo的源码,一睹庐山真面目。缓存

ExtensionLoader

ExtentionLoader是最核心的类,负责扩展点的加载和生命周期管理。咱们就以这个类开始吧。
Extension的方法比较多,比较经常使用的方法有:app

  • public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type)
  • public T getExtension(String name)
  • public T getAdaptiveExtension()

比较常见的用法有:dom

  • LoadBalance lb = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(loadbalanceName)
  • RouterFactory routerFactory = ExtensionLoader.getExtensionLoader(RouterFactory.class).getAdaptiveExtension()

说明:在接下来展现的源码中,我会将无关的代码(好比日志,异常捕获等)去掉,方便你们阅读和理解。this

*1. getExtensionLoader方法
这是一个静态工厂方法,入参是一个可扩展的接口,返回一个该接口的ExtensionLoader实体类。经过这个实体类,能够根据name得到具体的扩展,也能够得到一个自适应扩展。spa

public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
        // 扩展点必须是接口
        if (!type.isInterface()) {
            throw new IllegalArgumentException("Extension type(" + type + ") is not interface!");
        }
        // 必需要有@SPI注解
        if (!withExtensionAnnotation(type)) {
            throw new IllegalArgumentException("Extension type without @SPI Annotation!");
        }
        // 从缓存中根据接口获取对应的ExtensionLoader
        // 每一个扩展只会被加载一次
        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;
    }
    
private ExtensionLoader(Class<?> type) {
        this.type = type;
        objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
    }

*2. getExtension方法日志

public T getExtension(String name) {
        Holder<Object> holder = cachedInstances.get(name);
        if (holder == null) {
            cachedInstances.putIfAbsent(name, new Holder<Object>());
            holder = cachedInstances.get(name);
        }
        Object instance = holder.get();
        // 从缓存中获取,若是不存在就建立
        if (instance == null) {
            synchronized (holder) {
                instance = holder.get();
                if (instance == null) {
                    instance = createExtension(name);
                    holder.set(instance);
                }
            }
        }
        return (T) instance;
    }

getExtention方法中作了一些判断和缓存,主要的逻辑在createExtension方法中。咱们继续看createExtention方法。code

private T createExtension(String name) {
        // 根据扩展点名称获得扩展类,好比对于LoadBalance,根据random获得RandomLoadBalance类
        Class<?> clazz = getExtensionClasses().get(name);
        
        T instance = (T) EXTENSION_INSTANCES.get(clazz);
        if (instance == null) {
              // 使用反射调用nesInstance来建立扩展类的一个示例
            EXTENSION_INSTANCES.putIfAbsent(clazz, (T) clazz.newInstance());
            instance = (T) EXTENSION_INSTANCES.get(clazz);
        }
        // 对扩展类示例进行依赖注入
        injectExtension(instance);
        // 若是有wrapper,添加wrapper
        Set<Class<?>> wrapperClasses = cachedWrapperClasses;
        if (wrapperClasses != null && !wrapperClasses.isEmpty()) {
            for (Class<?> wrapperClass : wrapperClasses) {
                instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
            }
        }
        return instance;
}

createExtension方法作了如下事情:
*1. 先根据name来获得对应的扩展类。从ClassPath下META-INF文件夹下读取扩展点配置文件。router

*2. 使用反射建立一个扩展类的实例接口

*3. 对扩展类实例的属性进行依赖注入,即IoC。生命周期

*4. 若是有wrapper,添加wrapper,即AoP。

下面咱们来重点看下这4个过程 *1. 根据name获取对应的扩展类 先看代码:

相关文章
相关标签/搜索