Dubbbo 记录源码疑问

本文探讨了Dubbo 2.5.3版本的一些关键点,包括JVM配置接口URL、本地判断逻辑、异步调用实现、过滤器管理、SPI机制应用、Invoker调用路径以及默认配置的加载顺序等。通过深入分析,揭示了Dubbo框架如何根据URL参数进行适配以及其内部工作机制。
摘要由CSDN通过智能技术生成

 

dubbo 版本 2.5.3

1.JVM可以直接配置对应interface的url 或者指定dubbo路径文件,格式参照properties

ReferenceConfig.class line 185

String resolve = System.getProperty(interfaceName);
        String resolveFile = null;
        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.这里是否走本地的相关判断没看懂

ReferenceConfig.class line 338

URL tmpUrl = new URL("temp", "localhost", 0, map);
		final boolean isJvmRefer;
        if (isInjvm() == null) {
            if (url != null && url.length() > 0) { //指定URL的情况下,不做本地引用
                isJvmRefer = false;
            } else if (InjvmProtocol.getInjvmProtocol().isInjvmRefer(tmpUrl)) {
                //默认情况下如果本地有服务暴露,则引用本地服务.
                isJvmRefer = true;
            } else {
                isJvmRefer = false;
            }
        } else {
            isJvmRefer = isInjvm().booleanValue();
        }
		
		if (isJvmRefer) {
			URL url = new URL(Constants.LOCAL_PROTOCOL, NetUtils.LOCALHOST, 0, interfaceClass.getName()).addParameters(map);
			invoker = refprotocol.refer(interfaceClass, url);
            if (logger.isInfoEnabled()) {
                logger.info("Using injvm service " + interfaceClass.getName());
            }
		}
    public boolean isInjvmRefer(URL url) {
    	final boolean isJvmRefer;
    	String scope = url.getParameter(Constants.SCOPE_KEY);
    	//本身已经是jvm协议了,走正常流程就是了.
    	if (Constants.LOCAL_PROTOCOL.toString().equals(url.getProtocol())) {
    		isJvmRefer = false;
    	} else if (Constants.SCOPE_LOCAL.equals(scope) || (url.getParameter("injvm", false))) {
			//如果声明为本地引用
			//scope=local || injvm=true 等价 injvm标签未来废弃掉.
			isJvmRefer = true;
		} else if (Constants.SCOPE_REMOTE.equals(scope)){
			//声明了是远程引用,则不做本地引用
			isJvmRefer = false;
		} else if (url.getParameter(Constants.GENERIC_KEY, false)){
			//泛化调用不走本地
			isJvmRefer = false;
		} else if (getExporter(exporterMap, url) != null) {
			//默认情况下如果本地有服务暴露,则引用本地服务.
			isJvmRefer = true;
		} else {
			isJvmRefer = false;
		}
		return isJvmRefer;
    }

3.异步dubbo调用如何实现值传递有一块看不懂

FutureFilter.class line 123

后来看了这篇文章就清楚了一些 

https://blog.csdn.net/u013160932/article/details/81144471

    private void fireReturnCallback(final Invoker<?> invoker, final Invocation invocation, final Object result) {
        final Method onReturnMethod = (Method)StaticContext.getSystemContext().get(StaticContext.getKey(invoker.getUrl(), invocation.getMethodName(), Constants.ON_RETURN_METHOD_KEY));
        final Object onReturnInst = StaticContext.getSystemContext().get(StaticContext.getKey(invoker.getUrl(), invocation.getMethodName(), Constants.ON_RETURN_INSTANCE_KEY));

        //not set onreturn callback
        if (onReturnMethod == null  &&  onReturnInst == null ){
            return ;
        }
        
        if (onReturnMethod == null  ||  onReturnInst == null ){
            throw new IllegalStateException("service:" + invoker.getUrl().getServiceKey() +" has a onreturn callback config , but no such "+(onReturnMethod == null ? "method" : "instance")+" found. url:"+invoker.getUrl());
        }
        if (onReturnMethod != null && ! onReturnMethod.isAccessible()) {
            onReturnMethod.setAccessible(true);
        }
        
        Object[] args = invocation.getArguments();
        Object[] params ;
        Class<?>[] rParaTypes = onReturnMethod.getParameterTypes() ;
        if (rParaTypes.length >1 ) {
            if (rParaTypes.length == 2 && rParaTypes[1].isAssignableFrom(Object[].class)){
                params = new Object[2];
                params[0] = result;
                params[1] = args ;
            }else {
                params = new Object[args.length + 1];
                params[0] = result;
                System.arraycopy(args, 0, params, 1, args.length);
            }
        } else {
            params = new Object[] { result };
        }
        try {
            onReturnMethod.invoke(onReturnInst, params);
        } catch (InvocationTargetException e) {
            fireThrowCallback(invoker, invocation, e.getTargetException());
        } catch (Throwable e) {
            fireThrowCallback(invoker, invocation, e);
        }
    }

4. 一些因引用了外部包(包含自定义dubbo filter)可以使用url里面增加key的方式去掉对应的filter

类似: reference.filter=-xxx.XXXX

ProtocolFilterWrapper.class

    public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
        return "registry".equals(url.getProtocol())?this.protocol.refer(type, url):buildInvokerChain(this.protocol.refer(type, url), "reference.filter", "consumer");
    }

ExtensionLoader.class

    public List<T> getActivateExtension(URL url, String key, String group) {
        String value = url.getParameter(key);
        return this.getActivateExtension(url, value != null && value.length() != 0?Constants.COMMA_SPLIT_PATTERN.split(value):null, group);
    }

    public List<T> getActivateExtension(URL url, String[] values, String group) {
        List<T> exts = new ArrayList();
        List<String> names = values == null?new ArrayList(0):Arrays.asList(values);
        String name;
        if(!((List)names).contains("-default")) {
            this.getExtensionClasses();
            Iterator i$ = this.cachedActivates.entrySet().iterator();

            while(i$.hasNext()) {
                Entry<String, Activate> entry = (Entry)i$.next();
                name = (String)entry.getKey();
                Activate activate = (Activate)entry.getValue();
                if(this.isMatchGroup(group, activate.group())) {
                    T ext = this.getExtension(name);
                    if(!((List)names).contains(name) && !((List)names).contains("-" + name) && this.isActive(activate, url)) {
                        exts.add(ext);
                    }
                }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值