您的位置:首页 > 编程语言

DUBBO代码碎片

2018-09-05 17:08 295 查看
从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!");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Dubbo