SpringCloudAlibaba框架中,我们可以引入Nacos作为配置中心和注册中心,项目中配置好Nacos的地址并启动,项目服务会自动注册到Nacos中,配置也会从Nacos中进行拉取。那大家会不会有疑问:SpringCloudAlibaba到底是如何触发服务注册到Nacos的?又是如何触发Nacos配置文件拉取的? 因此,本文主要和大家探讨下面2个问题:
-
项目启动后,如何触发拉取Nacos中的配置文件? -
项目启动后,如何触发将服务注册到Nacos中的?
本文只会探究如何触发的问题。关于拉取配置文件和注册服务的源码实现,这里不作讨论。
浅浅回忆一下SpringCloud启动流程

SpringCloud的启动流程,在主应用启动阶段触发BootstrapApplicationListener监听器,此监听器触发Bootstrap Context的启动,此应用上下文最终作为主应用ApplicationContext的父级
如何触发Nacos配置拉取?
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
NacosPropertySourceLocator注册成Bean
在Bootstrap Context启动时,会加载BootstrapConfiguration定义的配置类,并完成配置类中定义的Bean的实例化。因此,NacosPropertySourceLocator会在Bootstrap Context启动完成时也完成Bean的实例化并注册到容器中
NacosPropertySourceLocator是PropertySourceLocator的一个实现
NacosPropertySourceLocator:在包com.alibaba.cloud.nacos.client中 PropertySourceLocator:在包org.springframework.cloud.bootstrap.config中

PropertySourceBootstrapConfiguration注册成Bean
SpringCloud项目中,必然会引入spring-cloud-context依赖,这个依赖中会加载PropertySourceBootstrapConfiguration,BootStrap Context启动完成后此类完成注册

PropertySourceBootstrapConfiguration是一个ApplicationContextInitializer,在Bootstrap Context中完后Bean的注册**,并应用于主应用run阶段的prepareContext中applyInitializers阶段**

在PropertySourceBootstrapConfiguration有个属性propertySourceLocators,通过自动装配的方式注入所有的PropertyurceLocator,第1步的**NacosPropertySourceLocator是PropertySourceLocator的实现,**因此被注入进来

主应用prepareContext中applyInitializers
主应用prepareContext时,会应用所有的ApplicationContextInitializer通过applyInitializers方法在完成applyInitializers之后**,**Nacos中的配置会出现在Environment中
-
主应用applyInitializers执行前

-
主应用applyInitializers执行后

通过定位,在applyInitializers方法中**,正是执行了PropertySourceBootstrapConfiguration#initialize方法结束后,Nacos的配置文件进入了Environment**

PropertySourceBootstrapConfiguration#initialize
在第2步时,PropertySourceBootstrapConfiguration将所有的PropertySourceLocator实现已经注入过来**,并且在initialize方法中进行使用,此时就使用到了NacosPropertySourceLocator**

NacosPropertySourceLocator#locate
我们可以自己Debug,进入NacosPropertySourceLocator#locateCollection,最后跟踪到NacosPropertySourceLocator#locate方法。
loadSharedConfiguration:加载shared-configs loadExtConfiguration:加载extension-configs loadApplicationConfiguration:加载应用配置文件
NacosConfigService#getConfig
最终Nacos配置文件的拉取,都是通过NacosConfigService进行拉取,指定group、dataId。 关于NacosConfigService具体拉取细节,这里不作解读NacosConfigService:在com.alibaba.nacos.client.config包中

小结
-
Nacos配置拉取是在主应用prepareContext阶段,在应用ApplicationContextInitializer时触发拉取的,具体的实现是PropertySourceBootstrapConfiguration调用所有PropertySourceLocator -
引入Nacos配置依赖后,NacosPropertySourceLocator作为一个**PropertySourceLocator实现,**进行相关的配置拉取任务
如何触发Nacos服务注册?
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
NacosAutoServiceRegistration注册成为Bean
spring-cloud-starter-alibaba-nacos-discovery引入后,引入了一个NacosServiceRegistryAutoConfiguration自动配置类

NacosServiceRegistryAutoConfiguration配置类声明了NacosAutoServiceRegistration这个Bean

监听器NacosAutoServiceRegistration
NacosAutoServiceRegistration本质上是一个ApplicationListener,用于监听WebServerInitializedEvent事件
AnnotationConfigServletWebServerApplicationContext的刷新
SpringBoot在应用类型是Servlet情况下,启动的应用上下文是AnnotationConfigServletWebServerApplicationContext此应用上下文refresh时,重写了onRefresh方法会创建一个内嵌web容器
WebServerStartStopLifecycle
在创建内嵌Web容器时,会注册一个WebServerStartStopLifecycle

WebServerStartStopLifecycle是SmartLifecycle

应用上下文finishRefresh
应用上下文finishRefresh,会触发WebServerStartStopLifecycle#start

具体触发过程,这里还有一段逻辑,我就不贴了,最终调用DefaultLifecycleProcessor#doStart完成了WebServerStartStopLifecycle#start触发

WebServerStartStopLifecycle#start
最终,WebServerStartStopLifecycle#start做了2件事
启动内嵌服务器 发布了一个ServletWebServerInitializedEvent事件

NacosAutoServiceRegistration接收事件
WebServerStartStopLifecycle#start发布ServletWebServerInitializedEvent事件,NacosAutoServiceRegistration接收到并进行处理

该事件处理会做下面几件事
发布InstancePreRegisteredEvent 注册服务 发布InstanceRegisteredEvent
服务注册
注册服务,是通过NacosServiceRegistry#register完成注册,具体注册逻辑由NamingService完成。

小结
-
在应用类型是Servlet时SpringBoot启动的应用上下文会重写refresh方法中的onRefresh方法,在onRefresh方法中创建内嵌服务器和注册一个WebServerStartStopLifecycle -
在应用上下文refresh方法的最后调用finishRefresh方法,该方法最终会触发WebServerStartStopLifecycle#start的执行 -
WebServerStartStopLifecycle#start会启动内嵌服务器,并发布ServletWebServerInitializedEvent事件 -
NacosAutoServiceRegistration作为ServletWebServerInitializedEvent事件的监听器会被自动配置,并被触发进行服务的注册
总结
好的,XiXi这里是把Nacos何时触发配置拉取和服务注册的原理,向大家表达了出来。希望大家可以理解XiXi想要表达的意思,同时也欢迎大家批评指正。
原文始发于微信公众号(溪溪技术笔记):SpringCloudAlibaba-Nacos整合原理
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/290316.html