Dubbo框架学习笔记(三)

来源:互联网 发布:数据库方案 编辑:程序博客网 时间:2024/05/28 17:07

Dubbo源码地址:https://github.com/alibaba/dubbo

Dubbo开发指南:http://dubbo.io/Developer+Guide-zh.htm


Dubbo服务发布

发布活动图:


服务发布方在spring的配置文件中配置如下:

<bean id="demoService"class="com.alibaba.dubbo.demo.provider.DemoServiceImpl" />

上面是在spring中配置的服务的具体实现,是spring中的一个普通的bean。

<dubbo:serviceinterface="com.alibaba.dubbo.demo.DemoService" ref=”demoService”/>

在上面的配置中,spring容器在启动的过程中会解析自定义的schema元素dubbo并转换成实际的配置实现ServiceBean ,并把服务暴露出去

ServiceBean除了继承dubbo自己的配置抽象类(ServiceConfig)以外,还实现了一系列的spring接口用来参与到spring容器的启动以及bean的创建过程中去。由于spring实例化的ServiceBean是单例模式的,在Spring的容器ApplicationContext的启动过程refresh过程中最后第二步会预先初始化单例的bean, 在bean的初始化过程会设置beanName,   设置容器applicationContext, 回调   InitializingBean的afterPropertiesSet。

最后一步finishRefresh会触发ContextRefreshedEvent事件, 而ServiceBean实现了ApplicationListener接口监听了此事件, 而在之前一步实例化的ServiceBean注册了这个事件,所以ServiceBean的onApplicationEvent(ApplicationEvent event)方法被触发, 在这个方法中触发了export方法来暴露服务。

public void afterPropertiesSet() throws Exception {    //如果没有配置provider        if (getProvider() == null) {        //获取IOC容器里的所有provider            Map<String, ProviderConfig> providerConfigMap = applicationContext == null ? null  : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class, false, false);            if (providerConfigMap != null && providerConfigMap.size() > 0) {                Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null  : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);                if ((protocolConfigMap == null || protocolConfigMap.size() == 0)                        && providerConfigMap.size() > 1) { // 兼容旧版本                    List<ProviderConfig> providerConfigs = new ArrayList<ProviderConfig>();                    for (ProviderConfig config : providerConfigMap.values()) {                        if (config.isDefault() != null && config.isDefault().booleanValue()) {                            providerConfigs.add(config);                        }                    }                    //关联所有providers                    if (providerConfigs.size() > 0) {                        setProviders(providerConfigs);                    }                } else {                    ProviderConfig providerConfig = null;                    for (ProviderConfig config : providerConfigMap.values()) {                        if (config.isDefault() == null || config.isDefault().booleanValue()) {                            if (providerConfig != null) {                                throw new IllegalStateException("Duplicate provider configs: " + providerConfig + " and " + config);                            }                            providerConfig = config;                        }                    }                    if (providerConfig != null) {                        setProvider(providerConfig);                    }                }            }        }        //如果没有配置application,且没有配置provider        if (getApplication() == null                && (getProvider() == null || getProvider().getApplication() == null)) {            //获取所有applications        Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);            if (applicationConfigMap != null && applicationConfigMap.size() > 0) {                ApplicationConfig applicationConfig = null;                for (ApplicationConfig config : applicationConfigMap.values()) {                    if (config.isDefault() == null || config.isDefault().booleanValue()) {                        if (applicationConfig != null) {                            throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);                        }                        applicationConfig = config;                    }                }                //关联application                if (applicationConfig != null) {                    setApplication(applicationConfig);                }            }        }        //如果没有配置module,且没有配置provider        if (getModule() == null                && (getProvider() == null || getProvider().getModule() == null)) {            Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);            if (moduleConfigMap != null && moduleConfigMap.size() > 0) {                ModuleConfig moduleConfig = null;                for (ModuleConfig config : moduleConfigMap.values()) {                    if (config.isDefault() == null || config.isDefault().booleanValue()) {                        if (moduleConfig != null) {                            throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);                        }                        moduleConfig = config;                    }                }                //关联module                if (moduleConfig != null) {                    setModule(moduleConfig);                }            }        }        //如果没有配置registries,且没有配置provider        if ((getRegistries() == null || getRegistries().size() == 0)                && (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().size() == 0)                && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) {            Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);            if (registryConfigMap != null && registryConfigMap.size() > 0) {                List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();                for (RegistryConfig config : registryConfigMap.values()) {                    if (config.isDefault() == null || config.isDefault().booleanValue()) {                        registryConfigs.add(config);                    }                }                //关联registries                if (registryConfigs != null && registryConfigs.size() > 0) {                    super.setRegistries(registryConfigs);                }            }        }        //如果没有配置monitor,且没有配置provider        if (getMonitor() == null                && (getProvider() == null || getProvider().getMonitor() == null)                && (getApplication() == null || getApplication().getMonitor() == null)) {            Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);            if (monitorConfigMap != null && monitorConfigMap.size() > 0) {                MonitorConfig monitorConfig = null;                for (MonitorConfig config : monitorConfigMap.values()) {                    if (config.isDefault() == null || config.isDefault().booleanValue()) {                        if (monitorConfig != null) {                            throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);                        }                        monitorConfig = config;                    }                }                //关联monitor                if (monitorConfig != null) {                    setMonitor(monitorConfig);                }            }        }        //如果没有配置protocol,且没有配置provider        if ((getProtocols() == null || getProtocols().size() == 0)                && (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().size() == 0)) {            Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null  : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);            if (protocolConfigMap != null && protocolConfigMap.size() > 0) {                List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();                for (ProtocolConfig config : protocolConfigMap.values()) {                    if (config.isDefault() == null || config.isDefault().booleanValue()) {                        protocolConfigs.add(config);                    }                }                //关联protocol                if (protocolConfigs != null && protocolConfigs.size() > 0) {                    super.setProtocols(protocolConfigs);                }            }        }        //如果没有配置path        if (getPath() == null || getPath().length() == 0) {            if (beanName != null && beanName.length() > 0                     && getInterface() != null && getInterface().length() > 0                    && beanName.startsWith(getInterface())) {                setPath(beanName);            }        }        //暴露provider        if (! isDelay()) {            export();        }    }


ServiceConfig.doExportUrls()执行具体的export过程

1. loadRegistries(true)

checkRegistry如果xml中没有配置注册中,从dubbo.properties中读取配置,构建RegistryConfig对象并赋值

构建注册中心URL统一数据模式集合List<registryUrl>

2. 因为dubbo支持多协议配置,遍历所有协议分别根据不同的协议把服务export到不同的注册中心上去

a) 判断是否是泛型暴露

b) 根据协议构建暴露服务的统一数据模型URL

c) 配置的了monitor加载monitor,并给URL设置MONITOR_KEY

d) 给注册中regitryUrl设置EXPORT_KEY值为前面构建的暴露服务url

e) 根据服务具体实现,实现接口以及regitryUrl从代理工厂ProxyFactory获取代理Invoker(继承于AbstractProxyInvoker),它是对具体实现的一种代理

f) Protocol.export(invoker) 暴露服务invoker

Invoker包含上一步传入的RegistryUrl, registryUrl的protocol值为registry

ProtocolListenerWrapper和ProtocolFilterWrapper对于协议为REGISTRY_PROTOCOL直接跳过,最终由RegistryProtocol处理export的过程


public synchronized void export() {          //如果provider没有配置          if (provider != null) {              //如果exporter没有配置使用provider所关联的exporter              if (export == null) {                  export = provider.getExport();              }              //如果delay(延迟暴露)没有配置,获取provider的delay              if (delay == null) {                  delay = provider.getDelay();              }          }          //如果不需要暴露接口则直接返回          if (export != null && ! export.booleanValue()) {              return;          }          //如果延迟暴露的时间(毫秒级)是存在的,开启线程并等待delay毫秒后开始暴露接口,否则直接执行暴露接口过程          if (delay != null && delay > 0) {              Thread thread = new Thread(new Runnable() {                  public void run() {                      try {                          Thread.sleep(delay);                      } catch (Throwable e) {                      }                      doExport();                  }              });              thread.setDaemon(true);              thread.setName("DelayExportServiceThread");              thread.start();          } else {              doExport();          }      }  
protected synchronized void doExport() {          //如果不需要暴露接口则抛出异常          if (unexported) {              throw new IllegalStateException("Already unexported!");          }          //如果已经暴露则不需要重复暴露          if (exported) {              return;          }          exported = true;          //如果interfaceName没配置(这样dubbo就无法找到需要暴露的service对象)则抛出异常          if (interfaceName == null || interfaceName.length() == 0) {              throw new IllegalStateException("<dubbo:service interface=\"\" /> interface not allow null!");          }          checkDefault();          //provider已经配置的情况下,如果application、module、registries、monitor、protocol中有未配置的均可以从provider获取          if (provider != null) {              if (application == null) {                  application = provider.getApplication();              }              if (module == null) {                  module = provider.getModule();              }              if (registries == null) {                  registries = provider.getRegistries();              }              if (monitor == null) {                  monitor = provider.getMonitor();              }              if (protocols == null) {                  protocols = provider.getProtocols();              }          }          if (module != null) {              if (registries == null) {                  registries = module.getRegistries();              }              if (monitor == null) {                  monitor = module.getMonitor();              }          }          if (application != null) {              if (registries == null) {                  registries = application.getRegistries();              }              if (monitor == null) {                  monitor = application.getMonitor();              }          }          if (ref instanceof GenericService) {              interfaceClass = GenericService.class;              if (StringUtils.isEmpty(generic)) {                  generic = Boolean.TRUE.toString();              }          } else {              try {                  interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()                          .getContextClassLoader());              } catch (ClassNotFoundException e) {                  throw new IllegalStateException(e.getMessage(), e);              }              checkInterfaceAndMethods(interfaceClass, methods);              checkRef();              generic = Boolean.FALSE.toString();          }          //如果是本地服务          if(local !=null){              //如果是本地服务在interfaceName属性后面加上Local              if(local=="true"){                  local=interfaceName+"Local";              }              Class<?> localClass;              try {                  //加载service                  localClass = ClassHelper.forNameWithThreadContextClassLoader(local);              } catch (ClassNotFoundException e) {                  throw new IllegalStateException(e.getMessage(), e);              }              if(!interfaceClass.isAssignableFrom(localClass)){                  throw new IllegalStateException("The local implemention class " + localClass.getName() + " not implement interface " + interfaceName);              }          }          //如果是远程服务          if(stub !=null){              if(stub=="true"){                  stub=interfaceName+"Stub";              }              Class<?> stubClass;              try {                  //加载service                  stubClass = ClassHelper.forNameWithThreadContextClassLoader(stub);              } catch (ClassNotFoundException e) {                  throw new IllegalStateException(e.getMessage(), e);              }              if(!interfaceClass.isAssignableFrom(stubClass)){                  throw new IllegalStateException("The stub implemention class " + stubClass.getName() + " not implement interface " + interfaceName);              }          }          //检查application          checkApplication();          //检查registries          checkRegistry();          //检查protocol          checkProtocol();          //将所有这些对象的属性关联到provider          appendProperties(this);          checkStubAndMock(interfaceClass);          if (path == null || path.length() == 0) {              path = interfaceName;          }          //暴露地址          doExportUrls();      }  
private void doExportUrls() {          //将注册的所有url匹配上对应的协议在服务端暴露出来          List<URL> registryURLs = loadRegistries(true);          for (ProtocolConfig protocolConfig : protocols) {              doExportUrlsFor1Protocol(protocolConfig, registryURLs);          }      }  
private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {          //如果没配置protocol则默认使用dubbo协议          String name = protocolConfig.getName();          if (name == null || name.length() == 0) {              name = "dubbo";          }          //获取主机地址          String host = protocolConfig.getHost();          if (provider != null && (host == null || host.length() == 0)) {              host = provider.getHost();          }          boolean anyhost = false;          if (NetUtils.isInvalidLocalHost(host)) {              anyhost = true;              try {                  host = InetAddress.getLocalHost().getHostAddress();              } catch (UnknownHostException e) {                  logger.warn(e.getMessage(), e);              }              if (NetUtils.isInvalidLocalHost(host)) {                  if (registryURLs != null && registryURLs.size() > 0) {                      for (URL registryURL : registryURLs) {                          try {                              //创建socket,连接到注册中心                              Socket socket = new Socket();                              try {                                  SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());                                  socket.connect(addr, 1000);                                  //获取服务所在主机地址                                  host = socket.getLocalAddress().getHostAddress();                                  break;                              } finally {                                  try {                                      socket.close();                                  } catch (Throwable e) {}                              }                          } catch (Exception e) {                              logger.warn(e.getMessage(), e);                          }                      }                  }                  if (NetUtils.isInvalidLocalHost(host)) {                      host = NetUtils.getLocalHost();                  }              }          }          //获取协议接口号          Integer port = protocolConfig.getPort();          if (provider != null && (port == null || port == 0)) {              port = provider.getPort();          }          final int defaultPort = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(name).getDefaultPort();          if (port == null || port == 0) {              port = defaultPort;          }          if (port == null || port <= 0) {              port = getRandomPort(name);              if (port == null || port < 0) {                  port = NetUtils.getAvailablePort(defaultPort);                  putRandomPort(name, port);              }              logger.warn("Use random available port(" + port + ") for protocol " + name);          }            //获取application、module、provider、protocol、exporter、registries、monitor所有属性          Map<String, String> map = new HashMap<String, String>();          if (anyhost) {              map.put(Constants.ANYHOST_KEY, "true");          }          map.put(Constants.SIDE_KEY, Constants.PROVIDER_SIDE);          map.put(Constants.DUBBO_VERSION_KEY, Version.getVersion());          map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));          if (ConfigUtils.getPid() > 0) {              map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));          }          appendParameters(map, application);          appendParameters(map, module);          appendParameters(map, provider, Constants.DEFAULT_KEY);          appendParameters(map, protocolConfig);          appendParameters(map, this);          if (methods != null && methods.size() > 0) {              for (MethodConfig method : methods) {                  appendParameters(map, method, method.getName());                  String retryKey = method.getName() + ".retry";                  if (map.containsKey(retryKey)) {                      String retryValue = map.remove(retryKey);                      if ("false".equals(retryValue)) {                          map.put(method.getName() + ".retries", "0");                      }                  }                  List<ArgumentConfig> arguments = method.getArguments();                  if (arguments != null && arguments.size() > 0) {                      for (ArgumentConfig argument : arguments) {                          //类型自动转换.                          if(argument.getType() != null && argument.getType().length() >0){                              Method[] methods = interfaceClass.getMethods();                              //遍历所有方法                              if(methods != null && methods.length > 0){                                  for (int i = 0; i < methods.length; i++) {                                      String methodName = methods[i].getName();                                      //匹配方法名称,获取方法签名.                                      if(methodName.equals(method.getName())){                                          Class<?>[] argtypes = methods[i].getParameterTypes();                                          //一个方法中单个callback                                          if (argument.getIndex() != -1 ){                                              if (argtypes[argument.getIndex()].getName().equals(argument.getType())){                                                  appendParameters(map, argument, method.getName() + "." + argument.getIndex());                                              }else {                                                  throw new IllegalArgumentException("argument config error : the index attribute and type attirbute not match :index :"+argument.getIndex() + ", type:" + argument.getType());                                              }                                          } else {                                              //一个方法中多个callback                                              for (int j = 0 ;j<argtypes.length ;j++) {                                                  Class<?> argclazz = argtypes[j];                                                  if (argclazz.getName().equals(argument.getType())){                                                      appendParameters(map, argument, method.getName() + "." + j);                                                      if (argument.getIndex() != -1 && argument.getIndex() != j){                                                          throw new IllegalArgumentException("argument config error : the index attribute and type attirbute not match :index :"+argument.getIndex() + ", type:" + argument.getType());                                                      }                                                  }                                              }                                          }                                      }                                  }                              }                          }else if(argument.getIndex() != -1){                              appendParameters(map, argument, method.getName() + "." + argument.getIndex());                          }else {                              throw new IllegalArgumentException("argument config must set index or type attribute.eg: <dubbo:argument index='0' .../> or <dubbo:argument type=xxx .../>");                          }                        }                  }              } // end of methods for          }            if (ProtocolUtils.isGeneric(generic)) {              map.put("generic", generic);              map.put("methods", Constants.ANY_VALUE);          } else {              String revision = Version.getVersion(interfaceClass, version);              if (revision != null && revision.length() > 0) {                  map.put("revision", revision);              }                String[] methods = Wrapper.getWrapper(interfaceClass).getMethodNames();              if(methods.length == 0) {                  logger.warn("NO method found in service interface " + interfaceClass.getName());                  map.put("methods", Constants.ANY_VALUE);              }              else {                  map.put("methods", StringUtils.join(new HashSet<String>(Arrays.asList(methods)), ","));              }          }          if (! ConfigUtils.isEmpty(token)) {              if (ConfigUtils.isDefault(token)) {                  map.put("token", UUID.randomUUID().toString());              } else {                  map.put("token", token);              }          }          if ("injvm".equals(protocolConfig.getName())) {              protocolConfig.setRegister(false);              map.put("notify", "false");          }          // 导出服务          String contextPath = protocolConfig.getContextpath();          if ((contextPath == null || contextPath.length() == 0) && provider != null) {              contextPath = provider.getContextpath();          }          //创建服务所在url          URL url = new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map);            if (ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)                  .hasExtension(url.getProtocol())) {              url = ExtensionLoader.getExtensionLoader(ConfiguratorFactory.class)                      .getExtension(url.getProtocol()).getConfigurator(url).configure(url);          }            String scope = url.getParameter(Constants.SCOPE_KEY);          //配置为none不暴露          if (! Constants.SCOPE_NONE.toString().equalsIgnoreCase(scope)) {                //配置不是remote的情况下做本地暴露 (配置为remote,则表示只暴露远程服务)              if (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {                  //暴露的地址是localhost所以远端无法访问                  exportLocal(url);              }              //如果配置不是local则暴露为远程服务.(配置为local,则表示只暴露远程服务)              if (! Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope) ){                  if (logger.isInfoEnabled()) {                      logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);                  }                  if (registryURLs != null && registryURLs.size() > 0                          && url.getParameter("register", true)) {                      for (URL registryURL : registryURLs) {                          url = url.addParameterIfAbsent("dynamic", registryURL.getParameter("dynamic"));                          URL monitorUrl = loadMonitor(registryURL);                          if (monitorUrl != null) {                              url = url.addParameterAndEncoded(Constants.MONITOR_KEY, monitorUrl.toFullString());                          }                          if (logger.isInfoEnabled()) {                              logger.info("Register dubbo service " + interfaceClass.getName() + " url " + url + " to registry " + registryURL);                          }                          //获取invoker                          Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));                          //根据协议将invoker暴露成exporter,具体过程是创建一个ExchangeServer,它会绑定一个ServerSocket到配置端口                          Exporter<?> exporter = protocol.export(invoker);                          //将创建的exporter放进链表便于管理                          exporters.add(exporter);                      }                  } else {                      Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);                        Exporter<?> exporter = protocol.export(invoker);                      exporters.add(exporter);                  }              }          }          this.urls.add(url);      }  




RegistryProtocol暴露服务过程

这里传入的Invoker是由RegistryUrl从ProxyFactory得到的Invoker

1. 从Invoker获取providerUrl,在获取cacheKey, 根据cacheKey获取本地缓存的ExporterChangeableWrapper(exporter代理,建立返回的exporter与protocol export出的exporter的对应关系), 如果存在返回。

2. 如果不存在,根据传入的 Invoker获取providerUrl, 在构建InvokerDelegete(originInvoker, providerUrl)

3. Protocol.exprot(invokerDelegete) 根据providerUrl 的协议(一般是dubbo协议)通过Protocol的设配类暴露务,得到exporter

4. 利用providerUr导出的exporter和invoker构建对象ExporterChangeableWrapper缓存到本地

5. 由Invoker得到registryUrl。

 在根据registryUrl从RegistryFactory获取Registry, 获取RegistryUrl的注册中心协议,这里我们拿zooKeeper协议为例。由dubbo的扩展机制得到的是ZookeeperRegistryFactory,得到注册器为ZookeeperRegistry

6. 由Invoker获取ProviderUrl在去除不需要在注册中心看到的字段得到registryProviderUrl

7. 注册中心(ZookeeperRegistry)注册registryProviderUrl

Registry.register(registryProviderUrl)

8. 由registryProviderUrl获取overrideSubscribeUrl,在构建OverrideListener

9. registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener) 注册中心订阅这个url, 用来当数据变化通知重新暴露, 哪zookeeper为例,暴露服务会在zookeeper生成一个节点,当节点发生变化的时候会触发overrideSubscribeListener的notify方法重新暴露服务

10.      构建并返回一个新的exporter实例

 

DubboProtocol暴露服务的过程

1. 从invoker获取统一数据模型url

2. 由url构建serviceKey(一般由端口,接口名,版本,group分组)

如:com.alibaba.dubbo.demo.DemoService:20880 这个是由接口和端口组成的

3. 构建DubboExporter放入本地map做缓存

4. 根据url openserver。 查找本地缓存以key为url.getAddress如果没有ExchangeServer创建。设置heartbeat时间,设置编码解码协议

根据url和ExchangeHandler  绑定server并返回(具体如何绑定专题介绍)

5. 返回DubboExporter对象

上图是服务提供者暴露服务的主过程:
首先ServiceConfig类拿到对外提供服务的实际类ref(如:HelloWorldImpl)
然后通过ProxyFactory类的getInvoker方法使用ref生成一个AbstractProxyInvoker实例,到这一步就完成具体服务到Invoker的转化。
接下来就是Invoker转换到Exporter的过程。
Dubbo的Invoker转为Exporter发生在DubboProtocol类的export方法,它主要是打开socket侦听服务,并接收客户端发来的各种请求,通讯细节由Dubbo自己实现。
有两个很重要的对象就是Invoker和Exporter
Dubbo会根据用户配置的协议调用不同协议的Invoker,再通过ReferenceConfig将Invoker的引用关联到Reference的ref属性上提供给消费端调用。
当用户调用service时dubbo会通过InvokerProxy调用Invoker的invoke的方法向服务端发起请

所以服务发布过程大致分成3步:

  1. 获取注册中心信息,构建协议信息,然后将其组合
  2. 通过ProxyFactory将HelloServiceImpl封装成一个Invoker执行
  3. 使用Protocol将invoker导出成一个Exporter(包括去注册中心注册服务等)

默默吐槽一下,为什么CSDN的图片上传了老是加载不出来!!

0 0