[SpringCloud] SpringCloud配置中心的核心原理

  • SpringCloud是什么时候去拉取配置中心的
  • 配置中心客户端的配置信息为什么要写在bootstrap文件中
  • 对象中注入的属性是如何动态刷新的
  • 一些开源的配置中心是如何整合SpringCloud的

文章目录

1.从SpringBoot的启动过程说起

SpringApplication的run方法的逻辑

1.1 大致过程

刷新前:

  1. 准备Environment, 也就是准备SpringBoot的整个外部化配置的对象
  2. 创建ApplicationContext
  3. 为ApplicationContext做一些准备工作

刷新中:

  1. 调用ApplicationContext#refresh方法来刷新容器

刷新后:

  1. 收尾的阶段

2.准备Environment的核心操作

prepareEnvironment方法的实现, 是拉取配置中心的核心

2.1 前置操作

在容器创建前, 会去加载spring.factories中的一些对象。

  1. org.springframework.context.ApplicationListener键对应的ApplicationListener的实现

  2. org.springframework.boot.SpringApplicationRunListener键对应的SpringApplicationRunListener的实现类



  3. 构造的时候会创建一个SimpleApplicationEventMulticaster,再将加载的ApplicationListener添加进去, SimpleApplicationEventMulticaster是用来发布事件用的

3.prepareEnvironment的核心逻辑

java 复制代码
listeners.environmentPrepared(environment);

将环境传入进容器。

会发布一个ApplicationEnvironmentPreparedEvent事件。

而对这个事件有两个特别重要的监听器:

  • ConfigFileApplicationListener: 用来处理配置文件的, 解析配置文件, 加入到Enviroment
  • BootstrapApplicationListener: 跟配置中心交互的

这些监听器都是通过前置操作从spring.factories配置文件中加载的

4.SpringCloud是如何巧妙地拉取配置的

在BootstrapApplicationListener中,他首先也会创建一个SpringApplication去执行。

  1. 本质上就是创建一个Spring容器

  2. 这个容器是专门用来跟配置中心交互的

  3. 这个容器在创建的时候会给它两个比较重要的配置

  4. 第一个就是设置这个容器所用的配置文件的名称, 默认就是bootstrap

  5. 第二个就是会加入一个配置类, BootstrapImportSelectorConfiguration

  6. 这个配置类又会通过@Import注解导入另一个配置类, BootstrapImportSelector

  7. BootstrapImportSelector实现了ImportSelector接口

  8. 容器启动时候, 调用BootstrapImportSelector的selectImports方法的实现获取到一些配置类

  9. 而BootstrapImportSelector的selectImports实现, 会加载所有的spring.factories中的键为org.springframework.cloud.bootstrap.BootstrapConfiguration的配置类

  10. 加载的是一个注解@BootstrapConfiguration, 和@EnableAutoConfiguration作用差不多, 都是导入配置类

  1. @BootstrapConfiguration会导入配置类ProperttySourceBootstrapConfiguration

  2. 这个配置类中会注入这么一个集合对象, propertySourceLocators, 获取配置中心中的配置

  3. PropertySourceBootstrapConfiguration#initialize(), 将配置放到Environment中

  4. 这样在ApplicationContext的刷新阶段就可以使用到配置中心的那些配置了

5.如何动态刷新Bean的属性

@RefreshScope

加了@RefreshScope注解的Bean, Spring会生成两个UserService的Bean

  • UserService的代理动态代理的Bean: 在其它类中需要注入一个UserService时, 注入的是代理Bean
  • UserService这个Bean: 使用这个注入的动态代理的Bean的时候, 调用的是UserService这个Bean

当配置中心客户端一旦感知到服务端的某个配置有变化的时候, 需要发布一个RefreshEvent事件来告诉SpringCloud配置有变动。

在SpringCloud中RefreshEventListener类会去监听这个事件

一旦监听到这个事件, SpringCloud会立刻重新拉去配置。

拉取配置的核心逻辑跟启动时拉取配置的核心逻辑是一样的。

通过BootstrapApplicationListener 来实现的。

RefreshEventListener监听RefreshEvent事件, 代码逻辑在ContextRefresher类中。

有了新的配置, 销毁UserService这个Bean, 代理对象保持不变。

6.开源配置中心是如何整合SpringCloud的

配置中心整合到SpringCloud:

  1. 实现PropertySourceLocator, 并且配置中心一些相关的Bean需要通过org.springframework.cloud.bootstrap.BootstrapConfiguration来装配到这个容器中
  2. 当配置发生变更需要发送RefreshEvent事件, 这部分配置中心一些相关的Bean配置肯定是需要通过自动装配来完成。

Nacos的spring.factories文件:

NacosConfigBootstrapConfiguration:

声明了一个NacosPropertySourceLocator这个Bean, 实现了PropertySourceLocator接口。

通过NacosConfigAutoConfiguration配置类来实现配置发生变更需要发送RefreshEvent事件。

这个Bean就实现了配置变化发送事件的操作。

相关推荐
掐指一算乀缺钱11 分钟前
SpringBoot 数据库表结构文档生成
java·数据库·spring boot·后端·spring
一叶飘零_sweeeet26 分钟前
为什么 Feign 要用 HTTP 而不是 RPC?
java·网络协议·http·spring cloud·rpc·feign
飞翔的佩奇40 分钟前
xxl-job适配sqlite本地数据库及mysql数据库。可根据配置指定使用哪种数据库。
数据库·spring boot·mysql·sqlite·xxl-job·任务调度
bug菌¹1 小时前
滚雪球学SpringCloud[4.1讲]: Spring Cloud Gateway详解
java·spring cloud·微服务
bug菌¹1 小时前
滚雪球学SpringCloud[4.2讲]: Zuul:Netflix API Gateway详解
spring·spring cloud·gateway
计算机学姐2 小时前
基于python+django+vue的影视推荐系统
开发语言·vue.js·后端·python·mysql·django·intellij-idea
小筱在线2 小时前
SpringCloud微服务实现服务熔断的实践指南
java·spring cloud·微服务
JustinNeil3 小时前
简化Java对象转换:高效实现大对象的Entity、VO、DTO互转与代码优化
后端
luoluoal3 小时前
java项目之基于Spring Boot智能无人仓库管理源码(springboot+vue)
java·vue.js·spring boot
ChinaRainbowSea3 小时前
十三,Spring Boot 中注入 Servlet,Filter,Listener
java·spring boot·spring·servlet·web