dubbo核心之服务端的Invoker(四)

一、服务端Invoker

  1. Invoker是一个代理,与dubbo中的SPI一样重要,在ServiceConfig中在调用export方法时会将一个invoker对象传递进去,分析下这个

    private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
    	//省略。。。
    	
    	//TODO  invoker -> 代理类
    	//proxyFactory是一个自适应扩展点,@Adaptive注解在方法上,因此是ProxyFactory$Adaptive
    	//并且SPI扩展文件还有包装类
    	//最终 proxyFactory = new StubProxyFactoryWrapper(new JavassistProxyFactory())
    	
    	//2.
        Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(EXPORT_KEY, url.toFullString()));
        //元数据的委派
        DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
        Exporter<?> exporter = protocol.export(wrapperInvoker);
        exporters.add(exporter);
    
    }
    
    2. JavassistProxyFactory
    @Override
    public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
        // TODO Wrapper cannot handle this scenario correctly: the classname contains '$'
        //这个方法会通过StringBuilder拼接代码动态的生成wrapper的实现类 并加载进jvm中
        //3.
        final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type);
        //返回一个invoker,  invoker.doInvoke() → wrapper.invokeMethod() → proxy.需要执行的方法() 
        return new AbstractProxyInvoker<T>(proxy, type, url) {
            @Override
            protected Object doInvoke(T proxy, String methodName,
                                      Class<?>[] parameterTypes,
                                      Object[] arguments) throws Throwable {
                return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
            }
        };
    }
    
    
    3. 
    public static Wrapper getWrapper(Class<?> c) {
        while (ClassGenerator.isDynamicClass(c)) // can not wrapper on dynamic class.
        {
            c = c.getSuperclass();
        }
    
        if (c == Object.class) {
            return OBJECT_WRAPPER;
        }
    
        Wrapper ret = WRAPPER_MAP.get(c);
        if (ret == null) {
       		//根据接口类型动态生成一个代理类
       		//这个代理类最重要的就是生成了 invokeMethod(proxy, methodName, parameterTypes, arguments)
       		//执行的时候直接调用被代理类的方法(没有用反射)也就是直接 proxy(ServiceConfig中传入的接口实现类)执行自己的方法();
            ret = makeWrapper(c);
            WRAPPER_MAP.put(c, ret);
        }
        return ret;
    }
    
    
  2. 按照流程继续走下去后会到DubboProtocol中的export方法

    1.
    @Override
    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
        URL url = invoker.getUrl();
    
        // 要暴露的服务地址
        String key = serviceKey(url);
        //将invoker封装为DubboExporter
        DubboExporter<T> exporter = new DubboExporter<T>(invoker, key, exporterMap);
        //缓存起来,后续给客户端调用
        exporterMap.put(key, exporter);
    
        //省略。。。
        return exporter;
    }
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值