Dubbo源码分析(三):Dubbo之服务端(Service)

article/2025/11/7 19:23:23

    

    如上图所示的Dubbo的暴露服务的过程,不难看出它也和消费者端很像,也需要一个像reference的对象来维护service关联的所有对象及其属性,这里的reference就是provider。由于ServiceBean实现了



InitializingBean接口,所有在Spring实例化这个bean后会调用接口方法afterPropertiesSet:

public void afterPropertiesSet() throws Exception {//如果没有配置providerif (getProvider() == null) {//获取IOC容器里的所有providerMap<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);}}//关联所有providersif (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,且没有配置providerif (getApplication() == null&& (getProvider() == null || getProvider().getApplication() == null)) {//获取所有applicationsMap<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;}}//关联applicationif (applicationConfig != null) {setApplication(applicationConfig);}}}//如果没有配置module,且没有配置providerif (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;}}//关联moduleif (moduleConfig != null) {setModule(moduleConfig);}}}//如果没有配置registries,且没有配置providerif ((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);}}//关联registriesif (registryConfigs != null && registryConfigs.size() > 0) {super.setRegistries(registryConfigs);}}}//如果没有配置monitor,且没有配置providerif (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;}}//关联monitorif (monitorConfig != null) {setMonitor(monitorConfig);}}}//如果没有配置protocol,且没有配置providerif ((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);}}//关联protocolif (protocolConfigs != null && protocolConfigs.size() > 0) {super.setProtocols(protocolConfigs);}}}//如果没有配置pathif (getPath() == null || getPath().length() == 0) {if (beanName != null && beanName.length() > 0 && getInterface() != null && getInterface().length() > 0&& beanName.startsWith(getInterface())) {setPath(beanName);}}//暴露providerif (! isDelay()) {export();}}

      Dubbo在确认了所有相关对象都配置后调用export方法开始暴露过程:

public synchronized void export() {//如果provider没有配置if (provider != null) {//如果exporter没有配置使用provider所关联的exporterif (export == null) {export = provider.getExport();}//如果delay(延迟暴露)没有配置,获取provider的delayif (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属性后面加上Localif(local=="true"){local=interfaceName+"Local";}Class<?> localClass;try {//加载servicelocalClass = 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 {//加载servicestubClass = 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);}}//检查applicationcheckApplication();//检查registriescheckRegistry();//检查protocolcheckProtocol();//将所有这些对象的属性关联到providerappendProperties(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();//一个方法中单个callbackif (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 {//一个方法中多个callbackfor (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();}//创建服务所在urlURL 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);}//获取invokerInvoker<?> 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);}

      整个暴露服务的流程就是首先检查配置是否完整然后获取协议和端口信息,通知registries自己已经注册可以提供服务最后创建Server绑定端口。这样用户就可以从配置的信息连接到Server并和Server通信远程调用方法了。






http://chatgpt.dhexx.cn/article/SnZWHm17.shtml

相关文章

Dubbo——初识RPC、Dubbo框架、使用直连方式实现Dubbo

文章目录&#xff1a; 1.RPC & 软件架构 1.1 单一应用架构 1.2 分布式微服务架构 1.3 RPC 2.Dubbo概述 2.1基本架构 2.2 dubbo支持的协议 3.直连方式实现dubbo 3.1 服务提供者的创建 3.2 服务消费者的创建 3.3 启动测试&#xff01;&#xff01;&#xff01; 1.…

分布式基本理解与Dubbo基本概念

学习dubbo之前&#xff0c;先要了解一下什么是分布式 分布式基础理论 什么是分布式系统 分布式系统是若干独立计算机的集合&#xff0c;这些计算机对于用户来说就像单个相关系统。 随着互联网的发展&#xff0c;网站应用的规模不断扩大&#xff0c;常规的垂直应用架构已无法…

Dubbo的原理和机制

Dubbo :是一个RPC框架&#xff0c;SOA框架&#xff1a; Dubbo缺省协议采用单一长连接和NIO异步通讯&#xff0c;适合于小数据量大并发的服务调用&#xff0c;以及服务消费者机器数远大于服务提供者机器数的情况。 作为RPC&#xff1a;支持各种传输协议&#xff0c;如dubbo,hes…

dubbo实现原理介绍

一、什么是dubbo Dubbo是Alibaba开源的分布式服务框架&#xff0c;它最大的特点是按照分层的方式来架构&#xff0c;使用这种方式可以使各个层之间解耦合&#xff08;或者最大限度地松耦合&#xff09;。从服务模型的角度来看&#xff0c; Dubbo采用的是一种非常简单的模型…

Dubbo-聊聊Dubbo协议

前言 Dubbo源码阅读分享系列文章&#xff0c;欢迎大家关注点赞 SPI实现部分 Dubbo-SPI机制 Dubbo-Adaptive实现原理 Dubbo-Activate实现原理 Dubbo SPI-Wrapper 注册中心 Dubbo-聊聊注册中心的设计 Dubbo-时间轮设计 通信 Dubbo-聊聊通信模块设计 什么是协议 在网…

dubbo客户端的实现

业界微服务大行其道。服务与服务之间的同学主要有有以下两大类。 阿里RPC框架&#xff1a;dubboRestFull风格的Http调用 我们知道Http接口我们找到PostMan这种Http客户端。 但是dubbo似乎并没有想关的客户端&#xff0c;我们调试的时常常需要同时打开两个以上的服务。 dubbo是…

dubbo组成原理-http服务消费端如何调用

dubbo协议已经用的很多了&#xff0c;这里来稍微介绍一下http协议&#xff0c;官方对http协议的说明简直少的让人发指。哈哈 百度大部分都只是讲了http服务端的配置 那就先从服务端的配置说起 dubbo需要的jar包这里就不说明了&#xff0c;网上找些maven的pom就可以 web.xml…

Dubbo基本原理机制

分布式服务框架&#xff1a; –高性能和透明化的RPC远程服务调用方案–SOA服务治理方案 -Apache MINA 框架基于Reactor模型通信框架&#xff0c;基于tcp长连接 Dubbo缺省协议采用单一长连接和NIO异步通讯&#xff0c;适合于小数据量大并发的服务调用&#xff0c;以及服务消费…

Dubbo基本原理与机制

1、什么是Dubbo Dubbo 是一款高性能、轻量级的开源 RPC 框架&#xff0c;提供服务自动注册、自动发现等高效服务治理方案&#xff0c; 可以和 Spring 框架无缝集成。 2、Dubbo依赖关系 1、服务消费者&#xff08;Consumer&#xff09;: 调用远程服务的服务消费方&#xff0c…

dubbo原理和机制

Dubbo 框架是用来处理分布式系统中&#xff0c;服务发现与注册以及调用问题的&#xff0c;并且管理调用过程。 一&#xff0c;工作流程&#xff1a; 服务提供者在启动的时候&#xff0c;会通过读取一些配置将服务实例化。Proxy 封装服务调用接口&#xff0c;方便调用者调用。…

Dubbo的原理与机制

​ Dubbo 前言 在介绍Dubbo之前先了解一下基本概念&#xff1a; Dubbo是一个RPC框架&#xff0c;RPC&#xff0c;即Remote Procedure Call&#xff08;远程过程调用&#xff09;&#xff0c;相对的就是本地过程调用&#xff0c;在分布式架构之前的单体应用架构和垂直应用架…

Dubbo基础及原理机制

1. 什么是Dubbo&#xff1f; Dubbo是 阿里巴巴公司开源的一个高性能RPC 分布式服务框架&#xff0c;使得应用可通过高性能的 RPC 实现服务的输出和输入功能&#xff0c;可以和 Spring框架无缝集成&#xff0c;现已成为 Apache 基金会孵化项目。 2. 为什么要用Dubbo&#xff1…

Dubbo原理和机制详解(非常全面)

Dubbo是一款Java RPC框架&#xff0c;致力于提供高性能的RPC远程服务调用方案。Dubbo 作为主流的微服务框架之一&#xff0c;为开发人员带来了非常多的便利。 本文我们重点详解 Dubbo 的原理机制 mikechen 目录 Dubbo核心功能Dubbo核心组件Dubbo的架构设计Dubbo调用流程 1️…

大地测量学基础(复习)第一部分

写在前面 这篇博文是用来复习课程“大地测量学基础”的&#xff0c;里面仅列出本人觉得这门课程比较重要的部分&#xff0c;希望能够帮助到有需要的朋友。 课本采用《大地测量学基础》孔祥元&#xff0c;武汉大学出版社。 前面已经有一篇“大地测量学基础&#xff08;复习&…

深入理解ArcGIS的地理坐标系、大地坐标系

1、引言 地理坐标&#xff1a;为球面坐标。 参考平面地是 椭球面,坐标单位:经纬度 大地坐标&#xff1a;为平面坐标。参考平面地是 水平面,坐标单位&#xff1a;米、千米等 地理坐标转换到大地坐标的过程可理解为投影。 &#xff08;投影&#xff1a;将不规则的地球曲面转…

GNSS定位中的不同高度概念及计算

文章目录 高度相关的几个基本概念RTKLIB中高度设置与计算参考文献 由于在GNSS定位中由多种高度表示&#xff0c;不同的高度概念很容易混淆&#xff0c;中英文对应有时候也容易搞混。因此整理了一下常用的两种高度——椭球高、正高的概念与计算&#xff0c;并且标注了对应的英文…

概念讲解:大地水准面 | 地球椭球体 | 参考椭球体 | 大地基准面 | 地图投影

文章目录 大地水准面地球椭球体参考椭球体大地基准面地图投影几个概念之间的关系相关文章 大地水准面 指平均海平面通过大陆延伸勾画出的一个连续的封闭曲面。大地水准面包围的球体称为大地球体。从大地水准面起算的陆地高度&#xff0c;称为绝对高度或海拔。 大地水准面是对地…

地图学的基础知识_天文坐标系_大地坐标系_地心坐标系及其相关概念

学习地图学&#xff0c;由于地理知识欠缺&#xff0c;学习相关投影知识还为时过早&#xff0c;需要复习一些基本概念。 阅读对象:测绘类 地球自然球体: 由地球自然表面所包围的的形体称为地球自然体。 地球自然球体形状:地球不是一个正球体&#xff0c;而是一个极半径略短&a…

大地测量学

大地测量学简答题复习 问&#xff1a;建立国家平面控制网的方法&#xff1f; 答&#xff1a; 常规大地测量&#xff1a;三角测量&#xff08;已知一个点的坐标&#xff0c;又精密测量了1&#xff0c;2点的边长和坐标方位角&#xff0c;依据三角形的正弦定理推测出其他边的长…

[复试——大地测量学]第一章节——2022/12/30

PART 1 大地测量学的定义 是在一定的时间和空间的参考系中&#xff0c;测量和描绘地球形状及其重力场并监测其变化&#xff0c;为人类活动提供地球空间信息的一门学科。 大地测量学的作用 1.建立地面控制网 2.精确测定大地控制点的三维位置以及其重力场参数 大地测量学的…