首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

读dubbo源码札记(一)

2012-11-12 
读dubbo源码笔记(一)首先看Extension扩展,相当于dubbo最底层核心如开发者所述:“Dubbo的扩展点加载从JDK标

读dubbo源码笔记(一)
首先看Extension扩展,相当于dubbo最底层核心
如开发者所述:“Dubbo的扩展点加载从JDK标准的SPI(Service Provider Interface)扩展点发现机制加强而来。" ,基本上与ServiceLoader类似(童鞋们,可以先看ServiceLoader源码再来看这个,比较理解),但功能增强
增强了 Wrapper 包装 ,cachedActivates 自动激活,Adaptive自适应,objectFactory Extension实例的属性获取对象方式,这4类。

下面看源码,整个Extension扩展 ,最主要类就只有一个 : ExtensionLoader
先来看 ExtensionLoader属性:

private static final Logger logger = LoggerFactory.getLogger(ExtensionLoader.class); //loggerFactory是dubbo自己封装 了log4j\jdkLog而来的。找不到log4j就去jdklog    private static final String SERVICES_DIRECTORY = "META-INF/services/";//静态,请看下面的地址,这个地方也可以配,但是如果自己又使用了ServiceLoader,2者会有冲突。    private static final String DUBBO_DIRECTORY = "META-INF/dubbo/";//静态,主要Extension扩展 的地方    private static final Pattern NAME_SEPARATOR = Pattern.compile("\\s*[,]+\\s*");//静态,这个不解释        private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<Class<?>, ExtensionLoader<?>>();//静态,放置所有ExtensionLoader    private static final ConcurrentMap<Class<?>, Object> EXTENSION_INSTANCES = new ConcurrentHashMap<Class<?>, Object>();//静态,放置所有Extension 实例对象    private final Class<?> type; //ExtensionLoader实例所对应的接口Class    private final ConcurrentMap<Class<?>, String> cachedNames = new ConcurrentHashMap<Class<?>, String>();//用于所有接口实现的Class 查找name,对于多name的取第一个        private final Reference<Map<String, Class<?>>> cachedClasses = new Reference<Map<String,Class<?>>>();//用于所有接口实现的name查找Class,对于多name,会存在 多name 对应一个Class    private final Map<String, Activate> cachedActivates = new ConcurrentHashMap<String, Activate>();//自动激活用private final ConcurrentMap<String, Reference<Object>> cachedInstances = new ConcurrentHashMap<String, Reference<Object>>();//本接口的实例    private volatile Class<?> cachedAdaptiveClass = null;    private final Reference<Object> cachedAdaptiveInstance = new Reference<Object>();//自适应实例private volatile Throwable createAdaptiveInstanceError;    private Set<Class<?>> cachedWrapperClasses;//包装类Class        private String cachedDefaultName;//默认使用扩展实例,由SPI注解value指定        private Map<String, IllegalStateException> exceptions = new ConcurrentHashMap<String, IllegalStateException>();    private final ExtensionFactory objectFactory;//扩展实例的属性获取Factory


下面是行为方法:
Public 方法

getExtensionLoader
    获取 ExtensionLoader 的唯一方式
    然后 会在 方法内部调用构造器 ,构造器中 为每一个ExtensionLoader 生成一个 ExtensionFactory 实例

getAdaptiveExtension
    大部分 使用ExtensionLoader  都会调用 AdaptiveClass 来进行选择处理
    这个方法 在第一次调用的时候会 载入  SERVICES_DIRECTORY  DUBBO_DIRECTORY 文件里面对应 的 ClassName ,所以这里是延迟载入

其余的Public 方法 没什么好说的

private 方法

在 getAdaptiveExtension  中载入的时候 调用过程如下

getAdaptiveExtension --createAdaptiveExtension --getAdaptiveExtensionClass --getExtensionClasses (载入文件ClassName)-----如果没有AdaptiveClass-----就会通过 createAdaptiveExtensionClass 字节码生成AdaptiveClass-------injectExtension

getAdaptiveExtension
    public T getAdaptiveExtension() {        Object instance = cachedAdaptiveInstance.get();        if (instance == null) {            if(createAdaptiveInstanceError == null) {                synchronized (cachedAdaptiveInstance) {                    instance = cachedAdaptiveInstance.get();                    if (instance == null) {                        try {                            instance = createAdaptiveExtension();                            cachedAdaptiveInstance.set(instance);                        } catch (Throwable t) {                            createAdaptiveInstanceError = t;                            rethrowAsRuntime(t, "fail to create adaptive instance: ");                        }                    }                }            }            else {                rethrowAsRuntime(createAdaptiveInstanceError, "fail to create adaptive instance: ");            }        }                return (T) instance;    }


createAdaptiveExtension -- 创建 AdaptiveExtension
private T createAdaptiveExtension() {        try {            return injectExtension((T) getAdaptiveExtensionClass().newInstance());        } catch (Exception e) {            throw new IllegalStateException("Can not create adaptive extenstion " + type + ", cause: " + e.getMessage(), e);        }    }


getAdaptiveExtensionClass -- 获取 AdaptiveExtension 里面包含了 2中 AdaptiveExtension 来源
private Class<?> getAdaptiveExtensionClass() {        getExtensionClasses();        if (cachedAdaptiveClass != null) {            return cachedAdaptiveClass;        }        return cachedAdaptiveClass = createAdaptiveExtensionClass();    }

getExtensionClasses 方法 装配文件 ,
然后判断 有没有cachedAdaptiveClass 
如果没有 createAdaptiveExtensionClass 字节码创建

injectExtension 方法-- 通过 objectFactory 来对 AdaptiveExtension Instance 进行 DI。

下面来说说这个
createAdaptiveExtensionClass 中的
createAdaptiveExtensionClassCode 方法
通过字节码生成 AdaptiveClass
但是
字节码生成的AdaptiveClass 严重依赖URL(主要是依赖URL里面的 protocol)。。看起来不那么优雅。
ExtensionLoader 作为 系统核心Loader模式,不应该过分只为Protocol 服务。


热点排行