Dubbo源码分析(5):ExtensionLoader
背景
Dubbo所有的模块加载是基于SPI机制的。在接口名的上一行加个@SPI注解表明要此模块要通过ExtensionLoader加载。基于SPI机制的扩展性比较好,在不修改原有代码,可以实现新模块的扩展。
获取AdaptiveExtension时序图
getAdaptiveExtension方法
代码图
从Hoder缓存取出目标对象,如果对象不为NULL直接返回对象本身。如果不存在且Throw对象为NULL,因为对象本身设置为全局的存在线程安全问题实例化对象时要加锁保证线程安全。实现化对象采用双锁单件设计模式。
参考
<headerFirst设计模式>书中的单件设计模式。
getExtensionClasses方法与getAdaptiveExtension方法类拟
loadExtensionClass方法
获取对应模块的所有Class对象,为动态实现化对象做准备工作。
loadFile方法
读取文件的每一行。格式:类的别名=类的包路径。类的路径转化成Class对象,判断Class对象是否有Adaptive注解,如果为TRUR,Class对象赋值给变量cachedAdaptiveClass.调用Class.getConstructor方法,如果没有抛出异常NoSuchMethodException,class对象添加到变量为cachedWrapperClassed的Set集合中。有异常NoSuchMethodException,Activate 对象增加到cachedActivates变量中,以Class对象为key,name为value保存到cachedNames的Map集合中。
createAdaptiveExtensionClass方法
模块中所有的类没有Active注解,需要动态创建一个。此时就要使用到该方法。
createAdaptiveExtensionClassCode方法
返回动态创建AdaptiveExtensionClassCode的String对象。
获取Extension对象
时序图
createExtension方法
通过name可以获取到class对象,再以class对象为key,来判断目标对象T是否缓存了。如果缓存了,返回对象。如果没有实例化对象并且调用对象所有的set方法,变量cacheWrapperClassed集合!=NULL及集合大小>0,实例化封装对象。
设计
装饰者设计模式