1. 概述
老话说的好:要善于思考,有创新意识。
言归正传,之前聊了 Springboot 的启动过程,今天来聊聊 Eureka Client 的注册过程。
2. Eureka Client 的注册过程
2.1 找入口
Eureka Client 留给我们的线索不多,似乎只有这个 @EnableDiscoveryClient 注解,我们进去看看
看到了一个 @Import 注解,进入到
EnableDiscoveryClientImportSelector 类看看
从逻辑看,后面会实例化
AutoServiceRegistrationConfiguration 这个类,进去这个类看看
有点高深。。。,似乎只有
AutoServiceRegistrationProperties 这个类有点用,翻译过来是 自动服务注册属性,应该和注册有关,来看看哪里调用它了吧。
进入
AbstractAutoServiceRegistration 类
实例化的时候用到了,跟它一起注入的有个 ServiceRegistry 对象,似乎这个对象和服务注册关系更大
这 ServiceRegistry 是个接口,里面有 register 方法,进入子类方法看看
好在只有一个子类 EurekaServiceRegistry,设置个断点,我们验证一下
2.2 EurekaServiceRegistry
断点果然到这里了,但从逻辑看,似乎并没有请求 Eureka Server 的代码出现。
我们把断点的方法栈往上跳一层,会看到下一步是向上下文中发布一个 InstanceRegisteredEvent 事件,看来之后某个监听器会调用这个事件
2.3 再次寻找线索
发布事件后,似乎断线了,我们到 jar 包里看看。(从监听器找线索也可以)
看到了 EurekaDiscoveryClient 这个类,根据经验应该是由这个类请求 Eureka Server 吧
似乎类里也没有请求 Eureka Server 的逻辑,但里面注入了一个 EurekaClient
打开 EurekaClient,是个接口,上面有一行 @ImplementedBy 注解,参数是 DiscoveryClient.class,进去看看
里面有个 register(注册)方法,设置个断点,试试
2.4 各种装饰
果然走到了,但似乎又去调了 SessionedEurekaHttpClient 的 register 方法
来到 SessionedEurekaHttpClient 类,我们发现 register 在它的父类 EurekaHttpClientDecorator 中,从名称就能看出这是个装饰器模式
父类的 register 方法,调用子类的 execute 方法,参数是一个匿名内部类,匿名内部类中实现的 execute 方法,参数是一个 EurekaHttpClient 的子类,然后再调用这个类的 register 方法
进入到 SessionedEurekaHttpClient 类的 excute 方法,果然加了装饰
相同的包下,有 RetryableEurekaHttpClient、
RedirectingEurekaHttpClient、MetricsCollectingEurekaHttpClient、SessionedEurekaHttpClient 4个装饰器类。
然后跟断点,发现是一系列的装饰。。。
2.5 真正注册
经过一系列的装饰,终于找到了
RestTemplateEurekaHttpClient 这个非装饰类
这个方法里要真正的发起请求了,urlPath 都有了
urlPath:
http://localhost:35000/eureka/apps/MY-EUREKA-CLIENT,应该就是这里了
最终,使用 httpClient 完成了请求的调用
2.6 总结
整个流程中用到了类的自动装载,上下文事件,装饰器模式,反射等知识,多看看确实能学到不少平时不常用的技术。
3. 综述
今天聊了一下 EurekaClient 的注册过程,希望可以对大家的工作有所帮助