源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

1. 概述

老话说的好:要善于思考,有创新意识。

言归正传,之前聊了 Springboot 的启动过程,今天来聊聊 Eureka Client 的注册过程。

2. Eureka Client 的注册过程

2.1 找入口

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

Eureka Client 留给我们的线索不多,似乎只有这个 @EnableDiscoveryClient 注解,我们进去看看

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

看到了一个 @Import 注解,进入到
EnableDiscoveryClientImportSelector 类看看

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

从逻辑看,后面会实例化
AutoServiceRegistrationConfiguration 这个类,进去这个类看看

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

有点高深。。。,似乎只有
AutoServiceRegistrationProperties 这个类有点用,翻译过来是 自动服务注册属性,应该和注册有关,来看看哪里调用它了吧。

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

进入
AbstractAutoServiceRegistration 类

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

实例化的时候用到了,跟它一起注入的有个 ServiceRegistry 对象,似乎这个对象和服务注册关系更大

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

这 ServiceRegistry 是个接口,里面有 register 方法,进入子类方法看看

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

好在只有一个子类 EurekaServiceRegistry,设置个断点,我们验证一下

2.2 EurekaServiceRegistry

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

断点果然到这里了,但从逻辑看,似乎并没有请求 Eureka Server 的代码出现。

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

我们把断点的方法栈往上跳一层,会看到下一步是向上下文中发布一个 InstanceRegisteredEvent 事件,看来之后某个监听器会调用这个事件

2.3 再次寻找线索

发布事件后,似乎断线了,我们到 jar 包里看看。(从监听器找线索也可以)

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

看到了 EurekaDiscoveryClient 这个类,根据经验应该是由这个类请求 Eureka Server 吧

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

似乎类里也没有请求 Eureka Server 的逻辑,但里面注入了一个 EurekaClient

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

打开 EurekaClient,是个接口,上面有一行 @ImplementedBy 注解,参数是 DiscoveryClient.class,进去看看

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

里面有个 register(注册)方法,设置个断点,试试

2.4 各种装饰

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

果然走到了,但似乎又去调了 SessionedEurekaHttpClient 的 register 方法

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

来到 SessionedEurekaHttpClient 类,我们发现 register 在它的父类 EurekaHttpClientDecorator 中,从名称就能看出这是个装饰器模式

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

父类的 register 方法,调用子类的 execute 方法,参数是一个匿名内部类,匿名内部类中实现的 execute 方法,参数是一个 EurekaHttpClient 的子类,然后再调用这个类的 register 方法

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

进入到 SessionedEurekaHttpClient 类的 excute 方法,果然加了装饰

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

相同的包下,有 RetryableEurekaHttpClient、
RedirectingEurekaHttpClient、MetricsCollectingEurekaHttpClient、SessionedEurekaHttpClient 4个装饰器类。

然后跟断点,发现是一系列的装饰。。。

2.5 真正注册

经过一系列的装饰,终于找到了
RestTemplateEurekaHttpClient 这个非装饰类

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

这个方法里要真正的发起请求了,urlPath 都有了

urlPath:
http://localhost:35000/eureka/apps/MY-EUREKA-CLIENT,应该就是这里了

源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程
源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程
源码分析 SpringCloud 2020.0.4 版本 EurekaClient 的注册过程

最终,使用 httpClient 完成了请求的调用

2.6 总结

整个流程中用到了类的自动装载,上下文事件,装饰器模式,反射等知识,多看看确实能学到不少平时不常用的技术。

3. 综述

今天聊了一下 EurekaClient 的注册过程,希望可以对大家的工作有所帮助

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容