Protocol接口有两个重要方法,一个是export()显露远程服务,另一个是refer()引用远程服务。

    /*** 暴露远程服务:<br>* 1. 协议在接收请求时,应记录请求来源方地址信息:RpcContext.getContext().setRemoteAddress();<br>* 2. export()必须是幂等的,也就是暴露同一个URL的Invoker两次,和暴露一次没有区别。<br>* 3. export()传入的Invoker由框架实现并传入,协议不需要关心。<br>* * @param <T> 服务的类型* @param invoker 服务的执行体* @return exporter 暴露服务的引用,用于取消暴露* @throws RpcException 当暴露服务出错时抛出,比如端口已占用*/@Adaptive<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;/*** 引用远程服务:<br>* 1. 当用户调用refer()所返回的Invoker对象的invoke()方法时,协议需相应执行同URL远端export()传入的Invoker对象的invoke()方法。<br>* 2. refer()返回的Invoker由协议实现,协议通常需要在此Invoker中发送远程请求。<br>* 3. 当url中有设置check=false时,连接失败不能抛出异常,并内部自动恢复。<br>* * @param <T> 服务的类型* @param type 服务的类型* @param url 远程服务的URL地址* @return invoker 服务的本地代理* @throws RpcException 当连接服务提供方失败时抛出*/@Adaptive<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;

显露服务和引用服务其实是一个相反的过程,从下边代码可以看出来。export(invoker),invoker是export的一个参数; 而在refer()中,它的返回结果是一个invoker,

protocol.export(proxy.getInvoker(service, DemoService.class, URL.valueOf("dubbo://127.0.0.1:9010/" + DemoService.class.getName())));
service = proxy.getProxy(protocol.refer(DemoService.class, URL.valueOf("dubbo://127.0.0.1:9010/" + DemoService.class.getName())));

1、export()显露服务,说白了就是启动服务,向外提供服务的过程。其中的关键方法是openServer(url);如果相应的server已存在,就重新设置一下就行,如果不存在就要去创建这个服务,创建的过程为createServer(URL url);

    private void openServer(URL url) {// find server.String key = url.getAddress();//client 也可以暴露一个只有server可以调用的服务。boolean isServer = url.getParameter(Constants.IS_SERVER_KEY,true);if (isServer) {ExchangeServer server = serverMap.get(key);if (server == null) {serverMap.put(key, createServer(url));} else {//server支持reset,配合override功能使用server.reset(url);}}}
    private ExchangeServer createServer(URL url) {//默认开启server关闭时发送readonly事件url = url.addParameterIfAbsent(Constants.CHANNEL_READONLYEVENT_SENT_KEY, Boolean.TRUE.toString());//默认开启heartbeaturl = url.addParameterIfAbsent(Constants.HEARTBEAT_KEY, String.valueOf(Constants.DEFAULT_HEARTBEAT));String str = url.getParameter(Constants.SERVER_KEY, Constants.DEFAULT_REMOTING_SERVER);if (str != null && str.length() > 0 && ! ExtensionLoader.getExtensionLoader(Transporter.class).hasExtension(str))throw new RpcException("Unsupported server type: " + str + ", url: " + url);url = url.addParameter(Constants.CODEC_KEY, Version.isCompatibleVersion() ? COMPATIBLE_CODEC_NAME : DubboCodec.NAME);ExchangeServer server;try {server = Exchangers.bind(url, requestHandler);} catch (RemotingException e) {throw new RpcException("Fail to start server(url: " + url + ") " + e.getMessage(), e);}str = url.getParameter(Constants.CLIENT_KEY);if (str != null && str.length() > 0) {Set<String> supportedTypes = ExtensionLoader.getExtensionLoader(Transporter.class).getSupportedExtensions();if (!supportedTypes.contains(str)) {throw new RpcException("Unsupported client type: " + str);}}return server;}

这个方法的关键,就是server = Exchangers.bind(url, requestHandler);,通过调用remoting包中的Exchanger.bind()来启动一个网络传输服务,并把相应的服务引用返回。

2、refer引用服务,说白了就是通过地址和服务接口,去实例化类,返回结果的过程。

首先将服务的接口和URL做为参数传给refer(),返回一个具体的协议实现类,

    public <T> Invoker<T> refer(Class<T> serviceType, URL url) throws RpcException {// create rpc invoker.DubboInvoker<T> invoker = new DubboInvoker<T>(serviceType, url, getClients(url), invokers);invokers.add(invoker);return invoker;}

接着就是根据invoker和接口类去实例化类,并返回具体类的过程

    public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));}

最后就可以根据具体返回的类对象,去调用相应的方法了。这就是简单的介绍了暴露服务和引用服务的过程。



dubbo_rpc显露服务和引用服务简析相关推荐

  1. 关于php车服务论文,「PHP」行车服务app后端代码简析

    之前发布了一篇关于我的 行车服务 app iOS 端代码简析的文章:文章地址. 此篇是对这个项目后端 iOS端代码地址: iOS代码,PHP代码.如果你觉得有帮助,希望能够点个 Star ,感谢~ 笔 ...

  2. 腾讯微服务框架-MSEC-源码简析(一)

    spp 主要进程分为3类: controller进程:主要负责controller,通过消息队列来监控proxy和worker的健康 proxy进程:负责接受用户请求,讲请求数据写入到共享内存 wor ...

  3. 计算机在气象上的应用浅论,简析计算机网络在气象服务中的应用原稿

    <简析计算机网络在气象服务中的应用(原稿).doc>由会员分享,可免费在线阅读全文,更多与<简析计算机网络在气象服务中的应用(原稿)>相关文档资源请在帮帮文库(www.woc8 ...

  4. CAS流程简析 服务端校验Ticket

    相关阅读 CAS基础组件 简介 CAS流程简析 服务端处理未携带Service登录请求 CAS流程简析 服务端处理携带Service登录请求 CAS基础组件 客户端过滤器 简介 用户访问客户端的请求若 ...

  5. 【Android源码分析】Android系统关键服务启动简析

    一.关于Android系统重要的进程 (1).init进程:init进程是Linux内核启动完成之后,启动的第一个用户进程,Android系统就是在这个进程的基础上启动起来的,进程pid为1.init ...

  6. Web地图服务规范(WMS、WMTS、TMS)简析

    Web地图服务规范(WMS.WMTS.TMS) 1.概况 Web地图服务规范包括WMS(网络地图服务).WMTS(网络地图瓦片服务).TMS(瓦片地图服务)等.WMTS服务和WMS服务都是由开发地理信 ...

  7. 轻量化服务,大道至简,触手可及

    随着物联网发展,每个用户手边都不再只有一个设备,我们发现在形态各异的智能设备中,逐渐出现原子化服务.轻应用.快应用等功能.这些功能设计都是将以往复杂的服务微小化.轻量化,以最简洁的方式呈现给用户,代表 ...

  8. 简析TCP的三次握手与四次分手【转】

    转自 简析TCP的三次握手与四次分手 | 果冻想 http://www.jellythink.com/archives/705 TCP是什么? 具体的关于TCP是什么,我不打算详细的说了:当你看到这篇 ...

  9. SIGMOD 2021 论文简析:当公交网络连接满足通勤需求时的公共交通规划 Public Transport Planning

    SIGMOD-2021 论文简析:当公交网络连接满足通勤需求时的公共交通规划 - Public Transport Planning: When Transit Network Connectivit ...

最新文章

  1. intitle:客服机器人代码_游戏客服能影响企业发展?千万别大意
  2. 关于单位基金资产净值
  3. [密码学基础][信息安全][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第11篇]DLP、CDH和DDH问题是什么?
  4. 电压源和电流的关联参考方向_结点电压法解题系列之四:电流源支路
  5. 超全十大经典排序算法及其分析
  6. 苹果将明年上半年iPhone出货量目标提高 30%
  7. GitHub:Python 强化学习实用指南
  8. 23、jQuery九类选择器/jQuery常用Method-API/jQuery常用Event-API
  9. iOS开发之更改状态栏字体颜色
  10. Chrome扩展开发指南(
  11. php开发pdf,使用PHP编写PDF(PDFLib)
  12. [Verilog]4 选 1 数据选择器
  13. Discuz仿集思街淘宝客网站模板/粉色淘客模板
  14. WES7 SKU WES7E和WES7P的区别
  15. MAC系统级鼠标手势功能软件BetterAndBetter
  16. win7计算机还原点建立,Win7中如何创建系统还原点
  17. Missing artifact oracle:ojdbc:jar:14:compile
  18. 浅谈vue的生命周期
  19. 波纹扩散特效(仿支付宝咻一咻功能)
  20. Unity之2D摄像机跟随

热门文章

  1. android 手机 没有手写,手机不能手写输入了,怎么办?
  2. 数控圈Fuanc三菱M70M80螺补自动补偿输入软件
  3. 第九届“中兴·图灵杯”人工智能程序设计大赛圆满落幕
  4. 通往当上CEO迎娶白富美的成功之路,送给你的读书清单《领导阶梯》
  5. beego excel 导出和读取
  6. 华为OD机试 - 二进制差异数(Java JS Python)
  7. 标准体重:男士体重 女士体重 ,写个函数,输入身高、体重、性别,输出偏重、正常
  8. clearfix清除浮动进化史
  9. java redis的同步_java同步系列之redis分布式锁进化史
  10. 彻底卸载Google Chrome