DUBBO代码碎片
2018-09-05 17:08
295 查看
从DUBBO的启动说起:
进入main方法,首先初始化下面代码:
一句代码即是整个DUBBO SPI的精髓所在,通过ExtensionLoader.getExtensionLoader(Container.class)获取Container(接口)扩展点loader,在通过new ExtensionLoader(Class<?> type)获取扩展点Container的loader时,判断Container非ExtensionFactory.class类型,需要通过下述代码完成ExtensionFactory实例的创建,并赋值给objectFactory (private final ExtensionFactory objectFactory):
->ExtensionLoader(Class<?> type)
->getAdaptiveExtension()//获取适配的扩展点实现类实例
->createAdaptiveExtension()//缓存中没有,创建适配的扩展点实现类实例
->getAdaptiveExtensionClass()//获取适配类
->getExtensionClasses()//从约定的配置文件中获取适配类
->loadExtensionClasses()//加载配置类
->loadFile()//从配置文件中加载配置类
->createAdaptiveExtensionClass//约定的配置文件中没有获取到适配类,则需要创建一个适配类
->createAdaptiveExtensionClassCode()//创建适配类的代码
->ExtensionLoader.getExtensionLoader(Compiler.class).getAdaptiveExtension()//获取编译器适配类实例
->compiler.compile(code, classLoader)//编译代码
其中loadFIle()方法会加载META-INF/dubbo/internal/com.alibaba.dubbo.common.extension.ExtensionFactory下的每一行,例如spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory
并通过反射对com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory进行实例化;
通过type.isAssignableFrom(clazz)判断SpiExtensionFactory是ExtensionFactory的子类,否则跑出异常。
通过clazz.isAnnotationPresent(Adaptive.class)判断SpiExtensionFactory上是否有@Adaptive注解,如果有则将其保存至cachedAdaptiveClass。
通过clazz.getConstructor(type)校验是否为AOP增强,即存在参数为其扩展点接口的构造函数,如果存在,将其缓存至Set<Class<?>>数组中,变量为wrappers。
如果上述构造方法不存在,则判断其是否存在无参构造。。。
最后将其key/value放入extensionClasses缓存中.
//TODO
完成上述初始化后,由于args为null,那么进入main方法后,DUBBO将执行如下代码片段:
即:读取dubbo.container配置的dubbo容器(至于dubbo.container配置在哪里,此处不细讲,一般从系统变量和环境变量的dubbo.properties.file或者类路径下的dubbo.properties文件中找,DUBBU读取配置文件的代码后续通过debug详细讲解),在classpath下面有一个文件dubbo.properties中记录了dubbo.container=log4j,spring
因此Container(接口)类型的的变量containers中便有了Container扩展点log4j和Spring两个扩展类的实例,通过下面代码添加:
DUBBO通过下述代码完成启动任务:
public class DemoProvider { public static void main(String[] args) { com.alibaba.dubbo.container.Main.main(args); } }
进入main方法,首先初始化下面代码:
private static final ExtensionLoader<Container> loader =ExtensionLoader.getExtensionLoader(Container.class);
一句代码即是整个DUBBO SPI的精髓所在,通过ExtensionLoader.getExtensionLoader(Container.class)获取Container(接口)扩展点loader,在通过new ExtensionLoader(Class<?> type)获取扩展点Container的loader时,判断Container非ExtensionFactory.class类型,需要通过下述代码完成ExtensionFactory实例的创建,并赋值给objectFactory (private final ExtensionFactory objectFactory):
ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()
->ExtensionLoader(Class<?> type)
->getAdaptiveExtension()//获取适配的扩展点实现类实例
->createAdaptiveExtension()//缓存中没有,创建适配的扩展点实现类实例
->getAdaptiveExtensionClass()//获取适配类
->getExtensionClasses()//从约定的配置文件中获取适配类
->loadExtensionClasses()//加载配置类
->loadFile()//从配置文件中加载配置类
->createAdaptiveExtensionClass//约定的配置文件中没有获取到适配类,则需要创建一个适配类
->createAdaptiveExtensionClassCode()//创建适配类的代码
->ExtensionLoader.getExtensionLoader(Compiler.class).getAdaptiveExtension()//获取编译器适配类实例
->compiler.compile(code, classLoader)//编译代码
其中loadFIle()方法会加载META-INF/dubbo/internal/com.alibaba.dubbo.common.extension.ExtensionFactory下的每一行,例如spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory
并通过反射对com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory进行实例化;
通过type.isAssignableFrom(clazz)判断SpiExtensionFactory是ExtensionFactory的子类,否则跑出异常。
通过clazz.isAnnotationPresent(Adaptive.class)判断SpiExtensionFactory上是否有@Adaptive注解,如果有则将其保存至cachedAdaptiveClass。
通过clazz.getConstructor(type)校验是否为AOP增强,即存在参数为其扩展点接口的构造函数,如果存在,将其缓存至Set<Class<?>>数组中,变量为wrappers。
如果上述构造方法不存在,则判断其是否存在无参构造。。。
最后将其key/value放入extensionClasses缓存中.
//TODO
完成上述初始化后,由于args为null,那么进入main方法后,DUBBO将执行如下代码片段:
public static final String CONTAINER_KEY = "dubbo.container"; if (args == null || args.length == 0) { String config = ConfigUtils.getProperty(CONTAINER_KEY, loader.getDefaultExtensionName()); args = Constants.COMMA_SPLIT_PATTERN.split(config); }
即:读取dubbo.container配置的dubbo容器(至于dubbo.container配置在哪里,此处不细讲,一般从系统变量和环境变量的dubbo.properties.file或者类路径下的dubbo.properties文件中找,DUBBU读取配置文件的代码后续通过debug详细讲解),在classpath下面有一个文件dubbo.properties中记录了dubbo.container=log4j,spring
因此Container(接口)类型的的变量containers中便有了Container扩展点log4j和Spring两个扩展类的实例,通过下面代码添加:
containers.add(loader.getExtension(args[i]))
DUBBO通过下述代码完成启动任务:
for (Container container : containers) { container.start(); logger.info("Dubbo " + container.getClass().getSimpleName() + " started!"); }
相关文章推荐
- qq解析代码碎片
- PHP笔记(碎片代码) - 选择MySQL数据库
- Dubbo测试代码(二)
- dubbo负载均衡代码分析3(加权轮询策略)
- iPhone代码碎片:处理objective-c里html特殊字符显示问题的一个函数
- 代码碎片
- SpringMVC代码碎片拾遗(01)_一个SpringMVC中对于领域模型绑定的不注意错误
- 第一代码第二版(郭霖著)笔记之第四章(探究碎片)
- 《第一行代码--Android》读书笔记之碎片
- Android Fragment 碎片 简单代码
- Tarena代码-一些代码碎片
- dubbo项目实战代码展示
- Firefly《暗黑世界》碎片合成部分代码
- 第一行代码笔记,第四章-------探究碎片
- (八) 构建dubbo分布式平台-maven构建ant-framework核心代码annotation
- 查看索引碎片,并生成重建索引代码
- dubbo 2.4.11源代码 - 扩展加载器
- Dubbo入门学习--动态代码编译器Compiler
- dubbo框架中一行日志代码引发的超时问题
- zookeeper注册中心两套环境 部分代码一致 例如两套不同的sso-server怎么区分 dubbo-monitor怎么监控