读dubbo源码笔记(一)

首先看Extension扩展,相当于dubbo最底层核心

如开发者所述:“Dubbo的扩展点加载从JDK标准的SPI(ServiceProviderInterface)扩展点发现机制加强而来。",基本上与ServiceLoader类似(童鞋们,可以先看ServiceLoader源码再来看这个,比较理解),但功能增强

增强了Wrapper包装,cachedActivates自动激活,Adaptive自适应,objectFactoryExtension实例的属性获取对象方式,这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_DIRECTORYDUBBO_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来对AdaptiveExtensionInstance进行DI。

下面来说说这个

createAdaptiveExtensionClass中的

createAdaptiveExtensionClassCode方法

通过字节码生成AdaptiveClass

但是

字节码生成的AdaptiveClass严重依赖URL(主要是依赖URL里面的protocol)。。看起来不那么优雅。

ExtensionLoader作为系统核心Loader模式,不应该过分只为Protocol服务。

相关推荐