`
flamezealot
  • 浏览: 20046 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

dubbo2.5.7 reference源码阅读

阅读更多
public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean

 afterPropertiesSet(),初始化consumer、application、module、registry、monitor信息,接下来

 Boolean b = isInit();
        if (b == null && getConsumer() != null) {
            b = getConsumer().isInit();
        }
        if (b != null && b.booleanValue()) {
            getObject();
        }

 会调到父类referenceConfig的get方法,get方法调用init方法,以下是init片段

1、对本地reslove文件的解析,如果在resolve文件里能找到key为interfaceName的,url设置成key对应的value

if (resolve == null || resolve.length() == 0) {
            resolveFile = System.getProperty("dubbo.resolve.file");
            if (resolveFile == null || resolveFile.length() == 0) {
                File userResolveFile = new File(new File(System.getProperty("user.home")), "dubbo-resolve.properties");
                if (userResolveFile.exists()) {
                    resolveFile = userResolveFile.getAbsolutePath();
                }
            }
            if (resolveFile != null && resolveFile.length() > 0) {
                Properties properties = new Properties();
                FileInputStream fis = null;
                try {
                    fis = new FileInputStream(new File(resolveFile));
                    properties.load(fis);
                } catch (IOException e) {
                    throw new IllegalStateException("Unload " + resolveFile + ", cause: " + e.getMessage(), e);
                } finally {
                    try {
                        if (null != fis) fis.close();
                    } catch (IOException e) {
                        logger.warn(e.getMessage(), e);
                    }
                }
                resolve = properties.getProperty(interfaceName);
            }
        }
        if (resolve != null && resolve.length() > 0) {
            url = resolve;
            if (logger.isWarnEnabled()) {
                if (resolveFile != null && resolveFile.length() > 0) {
                    logger.warn("Using default dubbo resolve file " + resolveFile + " replace " + interfaceName + "" + resolve + " to p2p invoke remote service.");
                } else {
                    logger.warn("Using -D" + interfaceName + "=" + resolve + " to p2p invoke remote service.");
                }
            }
        }

 

    2、载入dubbo.application配置,载入dubbo.service.shutdown.wait 优雅关机 配置

           checkApplication()

   3、如果reference的stub=true,判断是否有interface为参数的构造函数

 

if (ConfigUtils.isNotEmpty(stub)) {
            Class<?> localClass = ConfigUtils.isDefault(stub) ? ReflectUtils.forName(interfaceClass.getName() + "Stub") : ReflectUtils.forName(stub);
            if (!interfaceClass.isAssignableFrom(localClass)) {
                throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceClass.getName());
            }
            try {
                ReflectUtils.findConstructor(localClass, interfaceClass);
            } catch (NoSuchMethodException e) {
                throw new IllegalStateException("No such constructor \"public " + localClass.getSimpleName() + "(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
            }
        }

 

 

4、如果reference的mock=true或者mock=mock类名称

 

if (ConfigUtils.isNotEmpty(mock)) {
            if (mock.startsWith(Constants.RETURN_PREFIX)) {
                String value = mock.substring(Constants.RETURN_PREFIX.length());
                try {
                    MockInvoker.parseMockValue(value);//如果mock配置是 return xxx
                } catch (Exception e) {
                    throw new IllegalStateException("Illegal mock json value in <dubbo:service ... mock=\"" + mock + "\" />");
                }
            } else {
                Class<?> mockClass = ConfigUtils.isDefault(mock) ? ReflectUtils.forName(interfaceClass.getName() + "Mock") : ReflectUtils.forName(mock);//Mock类在mock=true时是interfaceName+Mock(package一致),mock也可以填具体的实现类名称
                if (!interfaceClass.isAssignableFrom(mockClass)) {//mockclass要实现interfaceClass
                    throw new IllegalStateException("The mock implementation class " + mockClass.getName() + " not implement interface " + interfaceClass.getName());
                }
                try {
                    mockClass.getConstructor(new Class<?>[0]);//Mock类需要有无参数构造函数
                } catch (NoSuchMethodException e) {
                    throw new IllegalStateException("No such empty constructor \"public " + mockClass.getSimpleName() + "()\" in mock implementation class " + mockClass.getName());
                }
            }
        }

   MockInvoker.parseMockValue(value);如下,可见mock:return xxx可以有null 、空对象、true、false、字符串、json串(map、list)

 

public static Object parseMockValue(String mock, Type[] returnTypes) throws Exception {
        Object value = null;
        if ("empty".equals(mock)) {
            value = ReflectUtils.getEmptyObject(returnTypes != null && returnTypes.length > 0 ? (Class<?>) returnTypes[0] : null);
        } else if ("null".equals(mock)) {
            value = null;
        } else if ("true".equals(mock)) {
            value = true;
        } else if ("false".equals(mock)) {
            value = false;
        } else if (mock.length() >= 2 && (mock.startsWith("\"") && mock.endsWith("\"")
                || mock.startsWith("\'") && mock.endsWith("\'"))) {
            value = mock.subSequence(1, mock.length() - 1);
        } else if (returnTypes != null && returnTypes.length > 0 && returnTypes[0] == String.class) {
            value = mock;
        } else if (StringUtils.isNumeric(mock)) {
            value = JSON.parse(mock);
        } else if (mock.startsWith("{")) {
            value = JSON.parseObject(mock, Map.class);
        } else if (mock.startsWith("[")) {
            value = JSON.parseObject(mock, List.class);
        } else {
            value = mock;
        }
        if (returnTypes != null && returnTypes.length > 0) {
            value = PojoUtils.realize(value, (Class<?>) returnTypes[0], returnTypes.length > 1 ? returnTypes[1] : null);
        }
        return value;
    }

 

 

5、接下来是把组装消费者url所需要的参数放到一个map

 

6、重头戏来了,创建动态代理

 

ref = createProxy(map);
    
url要么是reference指定的(点对点直连),要么是通过注册中心的配置组装的

组装主要是加上applicaiton、protocol相关信息,还要判断subscribe是否为dubbo.registry.subscribe是否为true,如果为rue则不返回url

invoker = refprotocol.refer(interfaceClass, url);
生成invoker,refprotocol对应不同的协议,dubbo协议实现类是DubboProtocol,以后再来看这个

// 创建服务代理
 return (T) proxyFactory.getProxy(invoker);

proxyFactory默认adaptive是javassist
 

 

分享到:
评论

相关推荐

    dubbo2.5.7 源码包

    dubbo2.5.7 源码包,来体验一次相同的东西,不相同的下载速度!

    dubbo-admin-2.5.7.war

    基于github源码编译,源码地址:https://github.com/alibaba/dubbo

    dubbo2.5.7服务

    这是已经打包好的dubbo2.5.7 maven 下载,可以直接编译,下载后直接部署在tomat即可使用。经过本人测试完全可以执行, 支持jdk1.6,jdk1.7 如果是jdk1.8的话需要修改tomcat中jdk应用,改成1.6或者1.7的

    dubbo-admin-2.5.7

    dubbo最新war包dubbo-admin-2.5.7,可以用在jdk1.8/jdk1.7等版本,亲测可用

    dubbo管理工具2.5.7版本

    dubbo-admin-2.5.7.war,dubbo的监控端工具,亲自maven编译打包

    dubbo-2.5.7.jar

    dubbo-2.5.7.jar

    dubbo-admin源码

    dubbo-admin源码dubbo-admin源码dubbo-admin源码dubbo-admin源码dubbo-admin源码dubbo-admin源码

    dubbo2.0-源码阅读

    学习dubbo中的一些总结 !

    dubbo 2.5.6 vs 2.5.7 源码差异分析

    dubbo 2.5.6 vs 2.5.7 源码差异分析,一点点小事情,希望对大家有帮助

    dubbo源码解析

    dubbo源码解析,dubbo源码解析,dubbo源码解析,dubbo源码解析

    dubbo-2.5.3源码

    dubbo-2.5.3源码,官网下载的可以直接编译使用,dubbo-2.5.3源码,官网下载的可以直接编译使用,dubbo-2.5.3源码,官网下载的可以直接编译使用

    dubbo-控制台使用源码

    dubbo2.5.7最新版本的源码,加上opensesame的源码,做备份使用,后续自己找也方便

    dubbo源码解析2

    dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.

    dubbo 源码

    dubbo 源码dubbo 源码dubbo 源码dubbo 源码dubbo 源码dubbo 源码dubbo 源码dubbo 源码

    alibaba-dubbo-dubbo-2.5.7-0-ge2d63ad.tar.gz

    alibaba-dubbo-dubbo-2.5.7-0-ge2d63ad.tar.gzalibaba-dubbo-dubbo-2.5.7-0-ge2d63ad.tar.gz

Global site tag (gtag.js) - Google Analytics