dubbo源码深度解读一之common模块

来源:互联网 发布:windows10装mac系统 编辑:程序博客网 时间:2024/06/07 20:18

前言:或许很多人会使用dubbo,但是阅读源码将使我们更加了解它,以及在未来对它进行改进优化。我就先把flag立在这里了,接下来这阵子将会深入源码进行学习和优化。做为一个要使用dubbo的程序员,必须需要深入理解它,因为dubbo已经停止了维护。

一,dubbo的分层架构
因为是第一篇,这些基础的东西需要先了解,对后面阅读源码也有好处,只做简单介绍,详细的可以看dubbo的官方手册。
1,Service层:该层与实际的业务内容相关,根据服务提供方和消费方提供对应的接口和实现
2,Config层:负责解析spring的配置文件,主要涉及ServiceConfig和ReferenceConfig
3,Proxy层:服务接口透明代理,生成服务的客户端Stub和服务端Skeleton,已ServiceProxy为中心,扩展接口为ProxyFactory
4,Registry层:封装服务地址的注册和发现,以服务URL为中心,扩展为RegistryFactory,Registry和RegistryService,可能没有服务注册中心,此时服务提供方直接暴露服务。
5,Cluster层:封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster,Directory,Router和LoadBalance,将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
6,Monitor层:RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory,Monitor和MonitorService
7,Protocol层:封装RPC调用,以Invocation和Result为中心,扩展接口为Protocol,Invoker和Exporter。Protocol是服务域,是Invoker暴露和引用的主功能入口,负责Invoker的生命周期管理。Invoker是实体域,是Dubbo的核心模型,其他模型都向他靠拢或者转换为它,它代表一个可执行体,可以向它发起Invoke调用,它有可能是一个本地实现或者一个远程的实现或者一个集群的实现
8,Exchange层:封装请求响应模型,同步转异步,以Request和Response为中心,扩展接口为Exchanger,ExchangeChannel,ExchangeClient和ExchangeServer。
9,Transport层:抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel,Transport,Client,Server和Codec。
10,Serialize层:可复用的一些工具,扩展接口为Serialization,ObjectInput,ObjectOutput和ThreadPool。

二,代码模块划分
1,dubbo-common 公共逻辑模块,包括Util类和通用模型。
2,dubbo-remoting 远程通讯模块,相当于Dubbo协议的实现,如果RPC用RMI协议则不需要使用此包。
3,dubbo-rpc 远程调用模块,抽象各种协议,以及动态代理,只包含一对一的调用,不关心集群的管理。
4,dubbo-cluster 集群模块,将多个服务提供方伪装为一个提供方,包括:负载均衡, 容错,路由等,集群的地址列表可以是静态配置的,也可以是由注册中心下发。
5,dubbo-registry 注册中心模块,基于注册中心下发地址的集群方式,以及对各种注册中心的抽象。
dubbo-monitor 监控模块,统计服务调用次数,调用时间的,调用链跟踪的服务。
6,dubbo-config 配置模块,是Dubbo对外的API,用户通过Config使用Dubbo,隐藏Dubbo所有细节。
7,dubbo-container 容器模块,是一个Standlone的容器,以简单的Main加载Spring启动,因为服务通常不需要Tomcat/JBoss等Web容器的特性,没必要用Web容器去加载服务

三,dubbo-config模块的代码阅读
1,beanutil包(主要是对class的一些定义和对反射的封装)
1.1 JavaBeanAccessor
(这个类相对容易理解,看定义和方法就可以了)

    public enum JavaBeanAccessor {    /** Field accessor. */    FIELD,    /** Method accessor.*/    METHOD,    /** Method prefer to field. */    ALL;    public static boolean isAccessByMethod(JavaBeanAccessor accessor) {        return METHOD.equals(accessor) || ALL.equals(accessor);    }    public static boolean isAccessByField(JavaBeanAccessor accessor) {        return FIELD.equals(accessor) || ALL.equals(accessor);    }}

1.2,JavaBeanDescriptor类。
该类主要定义了表示不同类型的常量

public final class JavaBeanDescriptor implements Serializable, Iterable<Map.Entry<Object, Object>> {    private static final long serialVersionUID = -8505586483570518029L;    public static final int TYPE_CLASS = 1;    public static final int TYPE_ENUM = 2;    public static final int TYPE_COLLECTION = 3;    public static final int TYPE_MAP = 4;    public static final int TYPE_ARRAY = 5;    /** @see com.alibaba.dubbo.common.utils.ReflectUtils#isPrimitive(Class)  */    public static final int TYPE_PRIMITIVE = 6;    public static final int TYPE_BEAN = 7;    private static final String ENUM_PROPERTY_NAME = "name";    private static final String CLASS_PROPERTY_NAME = "name";    private static final String PRIMITIVE_PROPERTY_VALUE = "value";//以下方法省略 }

1.3,JavaBeanSerializeUtil
该类对对象进行序列化成JavaBeanDescriptor。以及可以将JavaBeanDescriptor反序列化为对象。注意里面使用的cache类型为IdentityHashMap。

2,bytecode包
2.1 Proxy类
生成代理对象的工具类,主要是基于javassist的实现

public abstract class Proxy{    //利用AtomicLong自增获取一个long数组做为生存类的后缀,防止冲突    private static final AtomicLong PROXY_CLASS_COUNTER = new AtomicLong(0);    private static final String PACKAGE_NAME = Proxy.class.getPackage().getName();    public static final InvocationHandler RETURN_NULL_INVOKER = new InvocationHandler(){        public Object invoke(Object proxy, Method method, Object[] args){ return null; }    };    public static final InvocationHandler THROW_UNSUPPORTED_INVOKER = new InvocationHandler(){        public Object invoke(Object proxy, Method method, Object[] args){ throw new UnsupportedOperationException("Method [" + ReflectUtils.getName(method) + "] unimplemented."); }    };    //缓存的map对象    private static final Map<ClassLoader, Map<String, Object>> ProxyCacheMap = new WeakHashMap<ClassLoader, Map<String, Object>>();    private static final Object PendingGenerationMarker = new Object();    /**     * Get proxy.     *      * @param ics interface class array.     * @return Proxy instance.     */    public static Proxy getProxy(Class<?>... ics)    {        return getProxy(ClassHelper.getCallerClassLoader(Proxy.class), ics);    }    /**     * Get proxy.     * @param cl class loader.     * @param ics interface class array.     *      * @return Proxy instance.     */    public static Proxy getProxy(ClassLoader cl, Class<?>... ics)    {        if( ics.length > 65535 )            throw new IllegalArgumentException("interface limit exceeded");        StringBuilder sb = new StringBuilder();        //遍历所有入参的接口,以;进行分割        for(int i=0;i<ics.length;i++)        {            String itf = ics[i].getName();            if( !ics[i].isInterface() )                throw new RuntimeException(itf + " is not a interface.");            Class<?> tmp = null;            try            {                tmp = Class.forName(itf, false, cl);            }            catch(ClassNotFoundException e)            {}            if( tmp != ics[i] )                throw new IllegalArgumentException(ics[i] + " is not visible from class loader");            sb.append(itf).append(';');        }        // use interface class name list as key.        String key = sb.toString();        //通过classloader去缓存map中拿出对应的map。        Map<String, Object> cache;        synchronized( ProxyCacheMap )        {            cache = ProxyCacheMap.get(cl);            if( cache == null )            {                cache = new HashMap<String, Object>();                ProxyCacheMap.put(cl, cache);            }        }        Proxy proxy = null;        //如果查询获得对象,则返回,否则把key和PendingGenerationMarker插入        synchronized( cache )        {            do            {                Object value = cache.get(key);                if( value instanceof Reference<?> )                {                    proxy = (Proxy)((Reference<?>)value).get();                    if( proxy != null )                        return proxy;                }                if( value == PendingGenerationMarker )                {                    try{ cache.wait(); }catch(InterruptedException e){}                }                else                {                    cache.put(key, PendingGenerationMarker);                    break;                }            }            while( true );        }        long id = PROXY_CLASS_COUNTER.getAndIncrement();        String pkg = null;        ClassGenerator ccp = null, ccm = null;        try        {            ccp = ClassGenerator.newInstance(cl);            //用来存放接口所定义的所有方法,可以进行去重            Set<String> worked = new HashSet<String>();            List<Method> methods = new ArrayList<Method>();            for(int i=0;i<ics.length;i++)            {                if( !Modifier.isPublic(ics[i].getModifiers()) )                {                    String npkg = ics[i].getPackage().getName();                    if( pkg == null )                    {                        pkg = npkg;                    }                    else                    {                        if( !pkg.equals(npkg)  )                            throw new IllegalArgumentException("non-public interfaces from different packages");                    }                }                ccp.addInterface(ics[i]);                for( Method method : ics[i].getMethods() )                {                    String desc = ReflectUtils.getDesc(method);                    if( worked.contains(desc) )                        continue;                    worked.add(desc);                    int ix = methods.size();                    Class<?> rt = method.getReturnType();                    Class<?>[] pts = method.getParameterTypes();                    StringBuilder code = new StringBuilder("Object[] args = new Object[").append(pts.length).append("];");                    for(int j=0;j<pts.length;j++)                        code.append(" args[").append(j).append("] = ($w)$").append(j+1).append(";");                    code.append(" Object ret = handler.invoke(this, methods[" + ix + "], args);");                    if( !Void.TYPE.equals(rt) )                        code.append(" return ").append(asArgument(rt, "ret")).append(";");                    methods.add(method);                    ccp.addMethod(method.getName(), method.getModifiers(), rt, pts, method.getExceptionTypes(), code.toString());                }            }            if( pkg == null )                pkg = PACKAGE_NAME;            // create ProxyInstance class.            /**             * 创建代理实例对象ProxyInstance             * 类名为  pkg + “.poxy”+id = 包名 + “.poxy” +自增数值             * 添加静态字段Method[] methods;             * 添加实例对象InvokerInvocationHandler hanler             * 添加构造器参数是InvokerInvocationHandler             * 添加无参构造器             * 利用工具类ClassGenerator生成对应的字节码             *             */            String pcn = pkg + ".proxy" + id;            ccp.setClassName(pcn);            ccp.addField("public static java.lang.reflect.Method[] methods;");            ccp.addField("private " + InvocationHandler.class.getName() + " handler;");            ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{ InvocationHandler.class }, new Class<?>[0], "handler=$1;");            ccp.addDefaultConstructor();            Class<?> clazz = ccp.toClass();            clazz.getField("methods").set(null, methods.toArray(new Method[0]));            // create Proxy class.            /**             * 创建代理对象,它的newInstance(handler)方法用来创建基于我们接口的代理             * 代理对象名Proxy + id,继承于Proxy, 所以要实现newInstance方法             * 添加默认构造器             * 实现方法newInstance代码, new pcn(hadler) 这里pcn就是前面生成的代理对象类名             * 利用工具类ClassGenerator生成字节码并实例化对象返回             *             */            String fcn = Proxy.class.getName() + id;            ccm = ClassGenerator.newInstance(cl);            ccm.setClassName(fcn);            ccm.addDefaultConstructor();            ccm.setSuperClass(Proxy.class);            ccm.addMethod("public Object newInstance(" + InvocationHandler.class.getName() + " h){ return new " + pcn + "($1); }");            Class<?> pc = ccm.toClass();            proxy = (Proxy)pc.newInstance();        }        catch(RuntimeException e)        {            throw e;        }        catch(Exception e)        {            throw new RuntimeException(e.getMessage(), e);        }        finally        {            // release ClassGenerator            if( ccp != null )                ccp.release();            if( ccm != null )                ccm.release();            synchronized( cache )            {                if( proxy == null )                    cache.remove(key);                else                    cache.put(key, new WeakReference<Proxy>(proxy));                cache.notifyAll();            }        }        return proxy;    }

2.2 Wrapper类
是生成“运行时class代码”的工具类,
主要的方法有
1,makeWrapper类,生成一个继承于Wrapper的类
2,

public static Wrapper getWrapper(Class<?> c){    while( ClassGenerator.isDynamicClass(c) ) // can not wrapper on dynamic class.        c = c.getSuperclass();    //Object类型的    if( c == Object.class )        return OBJECT_WRAPPER;    //先去Wrapper缓存中查找    Wrapper ret = WRAPPER_MAP.get(c);    if( ret == null ) {        //缓存中不存在,生成Wrapper类,放到缓存        ret = makeWrapper(c);        WRAPPER_MAP.put(c,ret);    }    return ret;}

3,extension包
这是一个动态扩展包,dubbo包含了@SPI @Adaptive注解。dubbo如何利用配置和注解来做动态扩展呢?
3.1 ExtensionFactory类
根据class返回一个instance

@SPIpublic interface ExtensionFactory {    /**     * Get extension.     *      * @param type object type.     * @param name object name.     * @return object instance.     */    <T> T getExtension(Class<T> type, String name);}

接下来查看它的三个实现类
3.1.1 SpringExtensionFactory类
从ApplicationContext 获取这个bean

3.1.2 AdaptiveExtensionFactory类

@Adaptivepublic 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()) { // 将所有ExtensionFactory实现保存起来            list.add(loader.getExtension(name));        }        factories = Collections.unmodifiableList(list);    }    public <T> T getExtension(Class<T> type, String name) {        // 依次遍历各个ExtensionFactory实现的getExtension方法,一旦获取到Extension即返回        // 如果遍历完所有的ExtensionFactory实现均无法找到Extension,则返回null        for (ExtensionFactory factory : factories) {            T extension = factory.getExtension(type, name);            if (extension != null) {                return extension;            }        }        return null;    }}

相当于一个代理入口,他会遍历当前系统中所有的ExtensionFactory实现来获取指定的扩展实现,获取到扩展实现或遍历完所有的ExtensionFactory实现。这里调用了ExtensionLoader的getSupportedExtensions方法来获取ExtensionFactory的所有实现,又回到了ExtensionLoader类。

3.1.3 SpiExtensionFactory类
用ExtensionLoader来动态扩展,获取instance

3.2 ExtensionLoader类(重点,将详细解读)
每一个ExtensionLoader实例仅负责加载特定SPI扩展的实现,因此想要获取某个扩展的实现,首先要获取到该扩展对应的ExtensionLoader实例,下面我们就来看一下获取ExtensionLoader实例的工厂方法getExtensionLoade

@SuppressWarnings("unchecked")    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!");        }        //只接受@SPI注解注释的接口类型        if(!withExtensionAnnotation(type)) {            throw new IllegalArgumentException("Extension type(" + type +                     ") is not extension, because WITHOUT @" + SPI.class.getSimpleName() + " 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;    // 如果扩展类型是ExtensionFactory,那么则设置为null    // 这里通过getAdaptiveExtension方法获取一个运行时自适应的扩展类型(每个Extension只能有一个@Adaptive类型的实现,如果没有dubbo会动态生成一个类)    objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());}

从这个方法可以看到,我们调用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(); // 没有缓存的实例,创建新的AdaptiveExtension实例                        cachedAdaptiveInstance.set(instance);                    } catch (Throwable t) {                        createAdaptiveInstanceError = t;                        throw new IllegalStateException("fail to create adaptive instance: " + t.toString(), t);                    }                }            }        }        else {            throw new IllegalStateException("fail to create adaptive instance: " + createAdaptiveInstanceError.toString(), createAdaptiveInstanceError);        }    }    return (T) instance;}

首先检查缓存的adaptiveInstance是否存在,如果存在则直接使用,否则的话调用createAdaptiveExtension方法来创建新的adaptiveInstance并且缓存起来。也就是说对于某个扩展点,每次调用ExtensionLoader.getAdaptiveExtension获取到的都是同一个实例。

private Class<?> getAdaptiveExtensionClass() {    getExtensionClasses(); // 加载当前Extension的所有实现,如果有@Adaptive类型,则会赋值为cachedAdaptiveClass属性缓存起来    if (cachedAdaptiveClass != null) {        return cachedAdaptiveClass;    }    return cachedAdaptiveClass = createAdaptiveExtensionClass(); // 没有找到@Adaptive类型实现,则动态创建一个AdaptiveExtensionClass}private Map<String, Class<?>> getExtensionClasses() {    Map<String, Class<?>> classes = cachedClasses.get(); // 判断是否已经加载了当前Extension的所有实现类    if (classes == null) {        synchronized (cachedClasses) {            classes = cachedClasses.get();            if (classes == null) {                classes = loadExtensionClasses(); // 如果还没有加载Extension的实现,则进行扫描加载,完成后赋值给cachedClasses变量                cachedClasses.set(classes);            }        }    }    return classes;}

在getExtensionClasses方法中,首先检查缓存的cachedClasses,如果没有再调用loadExtensionClasses方法来加载,加载完成之后就会进行缓存。也就是说对于每个扩展点,其实现的加载只会执行一次。我们看下loadExtensionClasses方法:

private Map<String, Class<?>> loadExtensionClasses() {    final SPI defaultAnnotation = type.getAnnotation(SPI.class);    if(defaultAnnotation != null) {        String value = defaultAnnotation.value(); // 解析当前Extension配置的默认实现名,赋值给cachedDefaultName属性        if(value != null && (value = value.trim()).length() > 0) {            String[] names = NAME_SEPARATOR.split(value);            if(names.length > 1) { // 每个扩展实现只能配置一个名称                throw new IllegalStateException("more than 1 default extension name on extension " + type.getName()                        + ": " + Arrays.toString(names));            }            if(names.length == 1) cachedDefaultName = names[0];        }    }    // 从配置文件中加载扩展实现类    Map<String, Class<?>> extensionClasses = new HashMap<String, Class<?>>();    loadFile(extensionClasses, DUBBO_INTERNAL_DIRECTORY);    loadFile(extensionClasses, DUBBO_DIRECTORY);    loadFile(extensionClasses, SERVICES_DIRECTORY);    return extensionClasses;}

从代码里面可以看到,在loadExtensionClasses中首先会检测扩展点在@SPI注解中配置的默认扩展实现的名称,并将其赋值给cachedDefaultName属性进行缓存,后面想要获取该扩展点的默认实现名称就可以直接通过访问cachedDefaultName字段来完成,比如getDefaultExtensionName方法就是这么实现的。从这里的代码中又可以看到,具体的扩展实现类型,是通过调用loadFile方法来加载,分别从一下三个地方加载:

META-INF/dubbo/internal/
META-INF/dubbo/
META-INF/services/

创建自适应扩展点实现类型和实例化就已经完成了,下面就来看下扩展点自动注入的实现injectExtension:

private T injectExtension(T instance) {    try {        if (objectFactory != null) {            for (Method method : instance.getClass().getMethods()) {                if (method.getName().startsWith("set")                        && method.getParameterTypes().length == 1                        && Modifier.isPublic(method.getModifiers())) {// 处理所有set方法                    Class<?> pt = method.getParameterTypes()[0];// 获取set方法参数类型                    try {                        // 获取setter对应的property名称                        String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";                        Object object = objectFactory.getExtension(pt, property); // 根据类型,名称信息从ExtensionFactory获取                        if (object != null) { // 如果不为空,说set方法的参数是扩展点类型,那么进行注入                            method.invoke(instance, object);                        }                    } catch (Exception e) {                        logger.error("fail to inject via method " + method.getName()                                + " of interface " + type.getName() + ": " + e.getMessage(), e);                    }                }            }        }    } catch (Exception e) {        logger.error(e.getMessage(), e);    }    return instance;}

这里可以看到,扩展点自动注入的一句就是根据setter方法对应的参数类型和property名称从ExtensionFactory中查询,如果有返回扩展点实例,那么就进行注入操作。到这里getAdaptiveExtension方法就分析完毕了。

接下来看看getExtension

public T getExtension(String name) {    if (name == null || name.length() == 0)        throw new IllegalArgumentException("Extension name == null");    if ("true".equals(name)) {  // 判断是否是获取默认实现        return getDefaultExtension();    }    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;}
private T createExtension(String name) {    Class<?> clazz = getExtensionClasses().get(name); // getExtensionClass内部使用cachedClasses缓存    if (clazz == null) {        throw findException(name);    }    try {        T instance = (T) EXTENSION_INSTANCES.get(clazz); // 从已创建Extension实例缓存中获取        if (instance == null) {            EXTENSION_INSTANCES.putIfAbsent(clazz, (T) clazz.newInstance());            instance = (T) EXTENSION_INSTANCES.get(clazz);        }        injectExtension(instance); // 属性注入        // Wrapper类型进行包装,层层包裹        Set<Class<?>> wrapperClasses = cachedWrapperClasses;        if (wrapperClasses != null && wrapperClasses.size() > 0) {            for (Class<?> wrapperClass : wrapperClasses) {                instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));            }        }        return instance;    } catch (Throwable t) {        throw new IllegalStateException("Extension instance(name: " + name + ", class: " +                type + ")  could not be instantiated: " + t.getMessage(), t);    }}

从代码中可以看到,内部调用了getExtensionClasses方法来获取当前扩展的所有实现,而getExtensionClassse方法会在第一次被调用的时候将结果缓存到cachedClasses变量中,后面的调用就直接从缓存变量中获取了。这里还可以看到一个缓存EXTENSION_INSTANCES,这个缓存是ExtensionLoader的静态成员,也就是全局缓存,存放着所有的扩展点实现类型与其对应的已经实例化的实例对象(是所有扩展点,不是某一个扩展点),也就是说所有的扩展点实现在dubbo中最多都只会有一个实例

接下来看看getActivateExtension
方法主要获取当前扩展的所有可自动激活的实现。可根据入参(values)调整指定实现的顺序,在这个方法里面也使用到getExtensionClasses方法中收集的缓存数据

public List<T> getActivateExtension(URL url, String[] values, String group) {    List<T> exts = new ArrayList<T>();    List<String> names = values == null ? new ArrayList<String>(0) : Arrays.asList(values); // 解析配置要使用的名称    // 如果未配置"-default",则加载所有Activates扩展(names指定的扩展)    if (! names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) {        getExtensionClasses(); // 加载当前Extension所有实现,会获取到当前Extension中所有@Active实现,赋值给cachedActivates变量        for (Map.Entry<String, Activate> entry : cachedActivates.entrySet()) { // 遍历当前扩展所有的@Activate扩展            String name = entry.getKey();            Activate activate = entry.getValue();            if (isMatchGroup(group, activate.group())) { // 判断group是否满足,group为null则直接返回true                T ext = getExtension(name); // 获取扩展示例                // 排除names指定的扩展;并且如果names中没有指定移除该扩展(-name),且当前url匹配结果显示可激活才进行使用                if (! names.contains(name)                        && ! names.contains(Constants.REMOVE_VALUE_PREFIX + name)                         && isActive(activate, url)) {                    exts.add(ext);                }            }        }        Collections.sort(exts, ActivateComparator.COMPARATOR); // 默认排序    }    // 对names指定的扩展进行专门的处理    List<T> usrs = new ArrayList<T>();    for (int i = 0; i < names.size(); i ++) { // 遍历names指定的扩展名        String name = names.get(i);        if (! name.startsWith(Constants.REMOVE_VALUE_PREFIX)                && ! names.contains(Constants.REMOVE_VALUE_PREFIX + name)) { // 未设置移除该扩展            if (Constants.DEFAULT_KEY.equals(name)) { // default表示上面已经加载并且排序的exts,将排在default之前的Activate扩展放置到default组之前,例如:ext1,default,ext2                if (usrs.size() > 0) { // 如果此时user不为空,则user中存放的是配置在default之前的Activate扩展                    exts.addAll(0, usrs); // 注意index是0,放在default前面                    usrs.clear(); // 放到default之前,然后清空                }            } else {                T ext = getExtension(name);                usrs.add(ext);            }        }    }    if (usrs.size() > 0) { // 这里留下的都是配置在default之后的        exts.addAll(usrs); // 添加到default排序之后    }    return exts;}

四,URL
URL 本来是用来远程寻址的,dubbo 用它来暴露服务
所有扩展点参数都包含URL参数,URL作为上下文信息贯穿整个扩展点设计体系。
URL采用标准格式:protocol://username:password@host:port/path?key=value&key=value

例如:injvm://127.0.0.1/com.alibaba.dubbo.demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&generic=false&interface=com.alibaba.dubbo.demo.DemoService&loadbalance=roundrobin&methods=sayHello

总结:
第一次看源码,还有很多不太理解的,但是随着越来越深入,会慢慢清晰,同时也借鉴了很多大牛的博客,如果有什么错误的地方,欢迎指出。

原创粉丝点击