分布式中台实践-Dubbo源码分析

Dubbo源码导入Eclipse,打开源码,源码的结构分为cluster、common、container、filter、monitor、plugin、registry、remoting、rpc、serialization、lite部分。从代码的结构上来讲,Dubbo采用SPI的代码结构,即所有的结构都有可实现的接口。
首先从dubbo-config-api组件开始,其为配置文件解析做准备。结构上包括config、annotation、invoker、modal、support和utils构成。其中ServiceConfig为重点,其负责服务配置文件解析,它集成自AbstractServiceConfig(本类负责服务配置的数据结构),其顶级类继承自AbstractConfig(此类负责基本的属性、标注解析)。

AbstractConfig继承自 Serializable接口,另外它还启动了虚拟关闭进程,即虚拟机关闭时自动关闭相关的协议配置文件。其实现的代码如下:
     Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            public void run() {
                if (logger.isInfoEnabled()) {
                    logger.info("Run shutdown hook now.");
                }
                ProtocolConfig.destroyAll();
            }
        }, "DubboShutdownHook"));
    }
另外,为了实现服务程序的解析具备appendProperties、appendParameters、appendAttributes和appendAnnotation关键方法,每种方法通过反射机制实现相应属性和方法的添加。
appendProperties完成相应属性的调用,具体的实现代码如下:
    protected static void appendProperties(AbstractConfig config) {
        if (config == null) {
            return;
        }
        String prefix = "dubbo." + getTagName(config.getClass()) + ".";
        Method[] methods = config.getClass().getMethods();  //1)获取当前对象的方法;
        for (Method method : methods) {//2)遍历方法,判断方法为Set方法。
            try {
                String name = method.getName();
                if (name.length() > 3 && name.startsWith("set") && Modifier.isPublic(method.getModifiers())
                        && method.getParameterTypes().length == 1 && isPrimitive(method.getParameterTypes()[0])) {
                    String property = StringUtils.camelToSplitName(name.substring(3, 4).toLowerCase() + name.substring(4), ".");

                    String value = null;
//3)获取系统属性的参数类型和值;
                    if (config.getId() != null && config.getId().length() > 0) {
                        String pn = prefix + config.getId() + "." + property;
                        value = System.getProperty(pn);
                        if (!StringUtils.isBlank(value)) {
                            logger.info("Use System Property " + pn + " to config dubbo");
                        }
                    }
                    if (value == null || value.length() == 0) {
                        String pn = prefix + property;
                        value = System.getProperty(pn);
                        if (!StringUtils.isBlank(value)) {
                            logger.info("Use System Property " + pn + " to config dubbo");
                        }
                    }

//4)如果3为空,则获取系统属性的类型和值;
                    if (value == null || value.length() == 0) {
                        Method getter;
                        try {
                            getter = config.getClass().getMethod("get" + name.substring(3), new Class<?>[0]);
                        } catch (NoSuchMethodException e) {
                            try {
                                getter = config.getClass().getMethod("is" + name.substring(3), new Class<?>[0]);
                            } catch (NoSuchMethodException e2) {
                                getter = null;
                            }
                        }
                        if (getter != null) {
                            if (getter.invoke(config, new Object[0]) == null) {
                                if (config.getId() != null && config.getId().length() > 0) {
                                    value = ConfigUtils.getProperty(prefix + config.getId() + "." + property);
                                }
                                if (value == null || value.length() == 0) {
                                    value = ConfigUtils.getProperty(prefix + property);
                                }
                                if (value == null || value.length() == 0) {
                                    String legacyKey = legacyProperties.get(prefix + property);
                                    if (legacyKey != null && legacyKey.length() > 0) {
                                        value = convertLegacyValue(legacyKey, ConfigUtils.getProperty(legacyKey));
                                    }
                                }

                            }
                        }
                    }
//5)覆盖性操作。
                    if (value != null && value.length() > 0) {
                        method.invoke(config, new Object[]{convertPrimitive(method.getParameterTypes()[0], value)});
                    }
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
    }
其实现思路:
1)获取当前对象的方法;
2)遍历方法,判断方法为Set方法。
3)获取系统属性的参数类型和值;
4)如果3为空,则获取系统属性的类型和值;
5)覆盖性操作。
其他类的思路同上。通过以上的分析,不难发现Dubbo的配置文件采用不同的覆盖策略,其包括属性文件、配置文件和注解。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值