Spriing Cloud Config Server工作原理

spring boot 加载配置文件 阅读详情

说明:本文使用的源码基于Spring  Cloud Config Server 3.0.5版本

在 Spring Cloud Config 中,针对服务器端和客户端组件分别构建了 spring-cloud-config-server 和 spring-cloud-config-client 这两个代码工程。我们今天主要来看Spring Cloud Config Server的工作机制。

Spring Cloud Config Server工作机制

  1.  Spring Cloud Config Server配置加载过程

首先从@EnableConfigServer说起

@EnableConfigServer注解的源码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(ConfigServerConfiguration.class)
public @interface EnableConfigServer {

}

这里通过 @Import 注解引入了 ConfigServerConfiguration类该类中定义了一个 Marker 空类。在 Spring Boot 的自动配置体系中,这是常见的一种处理方式。这个 Marker 类的作用就是为了提供一个启动条件,而这个启动条件的唯一使用者就是 ConfigServerAutoConfiguration,如下所示:

@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(ConfigServerConfiguration.Marker.class)
@ConditionalOnProperty(name = ConfigServerProperties.PREFIX + ".enabled", matchIfMissing = true)
@EnableConfigurationProperties(ConfigServerProperties.class)
@Import({ EnvironmentRepositoryConfiguration.class, CompositeConfiguration.class, ResourceRepositoryConfiguration.class,
      ConfigServerEncryptionConfiguration.class, ConfigServerMvcConfiguration.class,
      ResourceEncryptorConfiguration.class })
public class ConfigServerAutoConfiguration {

}

        这里的 @ConditionalOnBean(ConfigServerConfiguration.Marker.class) 条件注解表示只有在类路径中构建了这个 Marker 类的实例时才会执行 ConfigServerAutoConfiguration 的处理。同时,这里又进一步导入了一批配置类,我们重点关注EnvironmentRepositoryConfiguration类,对于 Spring Cloud Config 而言,它把所有的配置信息抽象为一种 Environment(环境),而存储这些配置信息的地方就称为 EnvironmentRepository。EnvironmentRepository 就是带有配置仓库的配置中心实现方案的具体体现,它是一个接口,定义如下:

public interface EnvironmentRepository {

   Environment findOne(String application, String profile, String label);

   default Environment findOne(String application, String profile, String label, boolean includeOrigin) {
      return findOne(application, profile, label);
   }

}

Spring Cloud Config中把配置信息抽象为应用(application)、环境(profile)和版本(label)这三个维度进行管理,通过这三个维度,我们就可以确定唯一的一份配置数据。EnvironmentRepository 的实现类非常多,参见下图,从命名中基本都可以看出这些类是用于加载哪些不同类型的配置:

         从EnvironmentRepository 的实现来看,目前版本的实现已经有基于Git、Svn、Jdbc、Reids等第三方工具作为配置中心的实现。在EnvironmentRepositoryConfiguration类中我们看到了许多EnvironmentRepository的加载配置,其中默认的配置为DefaultRepositoryConfiguration。代码如下:

@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(value = EnvironmentRepository.class, search = SearchStrategy.CURRENT)
class DefaultRepositoryConfiguration {

   @Bean
   public MultipleJGitEnvironmentRepository defaultEnvironmentRepository(
         MultipleJGitEnvironmentRepositoryFactory gitEnvironmentRepositoryFactory,
         MultipleJGitEnvironmentProperties environmentProperties) throws Exception {
      return gitEnvironmentRepositoryFactory.build(environmentProperties);
   }

}

而GitRepositoryConfiguration继承了DefaultRepositoryConfiguration

@Configuration(proxyBeanMethods = false)
@Profile("git")
class GitRepositoryConfiguration extends DefaultRepositoryConfiguration {

}

也就是说 Spring Cloud Config 中默认使用 Git 作为配置仓库来完成配置信息的存储和管理,提供的 EnvironmentRepository 就是 MultipleJGitEnvironmentRepository,而 MultipleJGitEnvironmentRepository 则继承了抽象类 JGitEnvironmentRepository。

当服务器启动时,在 JGitEnvironmentRepository 中会决定是否调用 initClonedRepository() 方法来完成从远程 Git 仓库 Clone 代码。如果执行了这一操作,相当于会将配置文件从 Git 上 clone 到本地,然后再进行其他的操作。在 JGitEnvironmentRepository 抽象类中,提供了大量针对第三方 Git 仓库的操作代码,无论采用诸如 Git、SVN 等具体某一种配置仓库的实现方式,最终我们处理的对象都是位于本地文件系统中的配置文件。为了理解这点,我们需要围绕 MultipleJGitEnvironmentRepository 类从下向上回顾整个类层结构,如下图所示:

上图中,AbstractScmEnvironmentRepository 实现了 EnvironmentRepository 接口,同时也是 JGitEnvironmentRepository 的父类,它的 findOne 方法如下所示:

@Override
public synchronized Environment findOne(String application, String profile, String label, boolean includeOrigin) {
   NativeEnvironmentRepository delegate = new NativeEnvironmentRepository(getEnvironment(),
         new NativeEnvironmentProperties());
   Locations locations = getLocations(application, profile, label);
   delegate.setSearchLocations(locations.getLocations());
   Environment result = delegate.findOne(application, profile, "", includeOrigin);
   result.setVersion(locations.getVersion());
   result.setLabel(label);
   return this.cleaner.clean(result, getWorkingDirectory().toURI().toString(), getUri());
}

 我们看到AbstractScmEnvironmentRepository 的findOne方法调用了NativeEnvironmentRepository的findOne方法

@Override
public Environment findOne(String config, String profile, String label, boolean includeOrigin) {

   try {
      ConfigurableEnvironment environment = getEnvironment(config, profile, label);
      DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
      Map<org.springframework.core.env.PropertySource<?>, PropertySourceConfigData> propertySourceToConfigData = new HashMap<>();
      ConfigDataEnvironmentPostProcessor.applyTo(environment, resourceLoader, null,
            StringUtils.commaDelimitedListToSet(profile), new ConfigDataEnvironmentUpdateListener() {
               @Override
               public void onPropertySourceAdded(org.springframework.core.env.PropertySource<?> propertySource,
                     ConfigDataLocation location, ConfigDataResource resource) {
                  propertySourceToConfigData.put(propertySource,
                        new PropertySourceConfigData(location, resource));
               }
            });

      environment.getPropertySources().remove("config-data-setup");
      return clean(new PassthruEnvironmentRepository(environment).findOne(config, profile, label, includeOrigin),
            propertySourceToConfigData);
   }
   catch (Exception e) {
      String msg = String.format("Could not construct context for config=%s profile=%s label=%s includeOrigin=%b",
            config, profile, label, includeOrigin);
      String completeMessage = NestedExceptionUtils.buildMessage(msg,
            NestedExceptionUtils.getMostSpecificCause(e));
      throw new FailedToConstructEnvironmentException(completeMessage, e);
   }
}

从代码结构上,我们看到最终委托 PassthruEnvironmentRepository 完成配置文件的读取,然后通过 clean 方法完成本地文件地址与远程仓库之间地址的转换。ConfigDataEnvironmentUpdateListener用于监听Environment的更新。

2. 将配置暴漏给用户

在 Spring Cloud Config 中,通过 EnvironmentRepository 获取的配置信息最终通过 EnvironmentController 暴露给客户端应用程序进行。EnvironmentController 类比较简单,类的定义如下所示:

@RestController
@RequestMapping(method = RequestMethod.GET, path = "${spring.cloud.config.server.prefix:}")
public class EnvironmentController {

   private EnvironmentRepository repository;

   private ObjectMapper objectMapper;

   ......
}

EnvironmentController关键的成员变量只有两个,即 EnvironmentRepository 和 ObjectMapper。前者是具体某一个 EnvironmentRepository 的实例,而 ObjectMapper 用于当将结果序列化成 JSON 格式的配置数据。

EnvironmentController 提供了多种获取配置信息的方法,这些方法接收前面介绍的 application、profile、label 这三个参数。EnvironmentController 中最重要的方法就是如下所示的 defaultLabel 方法和 labelled 方法,这些方法暴露了最常用的获取配置的 HTTP 端点:

@RequestMapping(path = "/{name}/{profiles:.*[^-].*}", produces = MediaType.APPLICATION_JSON_VALUE)
public Environment defaultLabel(@PathVariable String name, @PathVariable String profiles) {
   return getEnvironment(name, profiles, null, false);
}

@RequestMapping(path = "/{name}/{profiles:.*[^-].*}", produces = EnvironmentMediaType.V2_JSON)
public Environment defaultLabelIncludeOrigin(@PathVariable String name, @PathVariable String profiles) {
   return getEnvironment(name, profiles, null, true);
}

@RequestMapping(path = "/{name}/{profiles}/{label:.*}", produces = MediaType.APPLICATION_JSON_VALUE)
public Environment labelled(@PathVariable String name, @PathVariable String profiles, @PathVariable String label) {
   return getEnvironment(name, profiles, label, false);
}

@RequestMapping(path = "/{name}/{profiles}/{label:.*}", produces = EnvironmentMediaType.V2_JSON)
public Environment labelledIncludeOrigin(@PathVariable String name, @PathVariable String profiles,
      @PathVariable String label) {
   return getEnvironment(name, profiles, label, true);
}

 以上就是Spring Cloud Config 来完成配置中心服务器端的构建过程。

2.设置Salesforce开发环境 Salesforce DX:salesforce Developer Experience (salesforce开发人员体验)LWC:Lightning Web Component(注意首字母是大写的,是一个概念,小写的话有组件本身的含义)CLI:Command Line Interface(命令行界面)version control system (VCS):版本控制系统。 阅读详情

相关推荐

【PowerHarmony】电鸿蒙学习记录-准备工作

将获取的“PowerHarmony_PHM_SDK_V1.0.1.0.tar.gz”进行解压。将获取的“code_1.91.1-1720564633_amd64.deb”进行解压。打开后可见所有文件夹,即可进行编辑开发,VSCode也可打开终端进行编译等调试。选择主控类型,我是用的是gd32f470,我选gd32f4xx。Open Folder路径选中SDK解压后根目录即可。选择对应系统类型,我的是小型的,我选mini。选好后即完成工程创建。

Allenzhu的博客 2737

Spring Boot - ConfigDataEnvironmentPostProcessor(Boot 2.4)搞定配置文件加载优先级

我们知道 以前我们的配置文件的优先级 是由 处理的 大意如下: 新版本 ConfigDataEnvironmentPostProcessor 从2.4开始, 改成了 ConfigDataEnvironmentPostProcessor我们继续看下 其实规则还是和老版本一样。

小工匠 4万+

管道机器人手臂机械结构设计cad【8张】+三维图+设计说明书+绛重

履带式管道机器人适用于各种管道环境,包括直管道、弯曲管道、水平管道、垂直管道等,其灵活性和适应性使得它可以应对不同形状和尺寸的管道,完成全面的检测和维护工作。管道机器人研究具有重要的现实意义和深远的社会影响,通过提高工作效率、降低人员风险、提升服务质量、节约成本资源和促进科技创新等方面的作用,为现代工程技术领域的发展和进步做出了积极的贡献。管道机器人是一种能够在管道内部执行各种任务的智能机器人,而管道机器人的机械臂对于管道机器人在管道内执行任务的灵活性、稳定性和效率至关重要。

kejigongjiang的博客 944

Spring Boot-加载配置文件ConfigDataEnvironmentPostProcessor

org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor是 Spring Boot 中的一个关键组件,它负责处理配置数据(config data),并将其应用于 Spring 应用上下文中。下面我们详细解读这个类的产生背景、作用和工作原理。

诗人不写诗 1070

IEEE802.11bf: WLAN Sensing Standard

下表为IEEE802.11bf 定义的使用情境 (Use Cases)

qinsd19的博客 1061

20240128 C#与SCPI协议实战:轻量级仪器控制库ScpiNet应用指南

本文详细介绍了轻量级C#库ScpiNet在仪器控制中的应用。相较于传统的NI-VISA,ScpiNet无需安装庞大运行时,通过纯C#实现直接与USB或以太网设备通信,支持跨厂商SCPI仪器。文章提供了从快速连接到实战封装、错误处理的完整指南,帮助开发者构建简洁高效的自动化测试系统。

h9j8k7l6m5n的博客 549

SpringBoot 系列之配置文件加载

在我们使用 SpringBoot 开发过程中,会在配置文件(application.properties 或者 application.yml)中写一些公共的配置,那么 SpringBoot 是如何加载配置文件的呢?

MichaelZ的博客 1545

JavaSwing_4.2: JDialog、JOptionPane(对话框)

JDialog,对话框。使用 JDialog 类可以创建自定义有的对话框,或者调用 JOptionPane 中的多个静态方法快速创建各种标准的对话框。JOptionPane是 JavaSwing 内部已实现好的,以静态方法的形式提供调用,能够快速方便的弹出要求用户提供值或向其发出通知的标准对话框。

谢TS的博客 7万+

springboot创建并配置环境(三) - 配置扩展属性(上集)

在上一篇文章:springboot创建并配置环境(二) - 配置基础环境中,我们介绍了springboot如何配置基础环境变量。本篇文章讨论如何处理配置文件。classpath路径下的**使用注解指定的文件、以及来自项目外部的配置文件**等。

理想万岁万万岁的博客 883

订餐平台餐厅信息抓取:使用Python爬虫获取商家信息和用户评价

在这篇博客中,我们展示了如何使用Python爬虫抓取订餐平台上的餐厅信息和用户评价数据。通过使用requests和Selenium,我们能够有效地从静态和动态网页中提取数据,并使用pandas和matplotlib对数据进行存储和分析。未来,您可以根据需求进一步扩展功能,例如增加错误处理、增加抓取多个页面的能力,或者使用高级技术如分布式爬虫来抓取更大规模的数据。

2201_76125261的博客 1651

23、工业物流中的多智能体路径规划与碰撞处理策略

本文探讨了工业4.0背景下工业物流中的多智能体路径规划(MAPF)与碰撞处理策略。分析了自动导引车(AGV)等移动资源的应用现状,综述了主流路径规划算法如A*、D*Lite、M*等,以及集中式与分布式碰撞检测方法。重点比较了五种碰撞避免策略:路径交叉、优先级、起始时间调整、无交叉路径和速度调整,提出了基于环境条件的策略选择流程,并通过流程图展示了评估、组合、测试与优化的全过程。文章强调应根据订单不确定性、时间约束、优先级和生产组织等因素综合选择或组合策略,以提升物流效率与系统可靠性。

mac99的博客 126

Spring Cloud 学习笔记 ——Spring Cloud Config 服务化

13.4 服务化 前面讲到了 Spring Cloud config 的 安全管理,但是例子中 config server 和 config client 都是单体服务,没有放到注册中心去,下面简单演示集成到 Eureka 服务。 1.首先启动 Eureka 服务端,然后为了 config server 和 config client 能注册到 Eureka,都在 pom.xml 添加 Eureka Client 依赖 <dependency> <group

XiaoMing学习分享博文 196

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Spring Cloud技术分析(5)- spring cloud config

地址:http://tech.lede.com/    在分布式系统中,spring cloud config 提供一个服务端和客户端去提供可扩展的配置服务。我们可用用配置服务中心区集中的管理所有的服务的各种环境配置文件。配置服务中心采用Git的方式存储配置文件,因此我们很容易部署修改,有助于对环境配置进行版本管理。一、简介1.为什么要配置中心?一个应用中不只是代码,还需要连接资源和其它应用,经常...

路漫漫其修远兮 250

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

SpringBoot扩展点EnvironmentPostProcessor

一、背景 之前项目中用到了Apollo配置中心,对接Apollo配置中心后,配置中心的属性就可以在程序中使用了,那么这个是怎么实现的呢?配置中心的属性又是何时加载到程序中的呢?那么我们如果找到了这个是怎么实现的是否就可以从任何地方加载配置属性、配置属性的加解密功能呢? 二、需求 需求 从上图中得知,我们的需求很简单,即我们自己定义的属性需要比配置文件中的优先级更高。 三、分析 1、什么时候向SpringBoot中加入我们自己的配置属性 当我们想在Bean中使用配置属性时,那么我们的配置属.

qwer123451234123的博客 790

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

SpringBoot2.7 核心源码解读

SpringBoot2.7 核心源码解读

MCN的博客 1990

深入解析spring boot配置加载原理,配置文件的加载顺序是怎么实现的?

1.spring boot的配置是如何加载的 2.spring boot的bootstrap配置文件为什么不生效 3.spring boot配置的加载顺序怎么实现

qq_26751319的博客 6494

Spring Boot 配置文件加载源码解析与升级遇到的坑

SpringBoot 配置文件加载 SpringBoot2.4以后 SpringBoot2.4及以后,取消ConfigFileApplicationListener,改成了EnvironmentPostProcessor、RandomPropertySource EnvironmentPostProcessor EnvironmentPostProcessor子类实现的加载本质上SpringFactoriesLoader进行类的加载,加载时机是通过ApplicationEnvironmentPrep

lzhfdxhxm的博客 1093

SpringBoot源码解析(七)EnvironmentPostProcessor

本文将重点介绍SpringBoot提供给我们的另一个扩展点EnvironmentPostProcessor,它允许我们到任意的指定目录、以任意的方式加载一组配置,并赋予任意的优先级 上文对prepareEnvironment方法的configureEnvironment做了一个收尾,本文继续看第三行代码listeners.environmentPrepared private ConfigurableEnvironment prepareEnvironment(SpringApplication.

m0_37298252的博客 2947

springboot启动流程

WebApplicationType 根据类路径是否有Servlet和Reactive的类来确定,如果有DispatcherHandler,并且没有DispatcherServlet和org.glassfish.jersey.servlet.ServletContainer,用Reactive,创建AnnotationConfigReactiveWebServerApplicationContext;CommandLineRunner 获取到的是原生的、未解析的main方法参数,

baidu_32223873的博客 416

[Spring-Boot 2.6.6源码解析系列]-4-配置信息加载全解析-(开发自己的配置中心必备功能)

目录3-配置信息加载全解析-(开发自己的配置中心必备功能)3.1 简介3.2 创建一个ConfigurableEnvironment对象3.2.1 ConfigurableEnvironment对象简介3.2.2 ConfigurableEnvironment对象的创建3.2.3 ApplicationEnvironment的构造器执行过程3.3 广播environmentPrepared事件 3-配置信息加载全解析-(开发自己的配置中心必备功能) 3.1 简介 上一个博客中说了配置环境信息Configur

宋小生-中间件 677

Spring boot源码之EnvironmentPostProcessor

EnvironmentPostProcessor主要是在环境实例Environment准备好后,发布EnvironmentPreparedEvent时,EnvironmentPostProcessorApplicationListener响应该事件,调用各个EnvironmentPostProcessor.postProcessEnvironment对环境实例Environment进行后置处理。EnvironmentPostProcessor配置在spring.factories中,主要涉及。

lft18的博客 1233

springboot扩展点之 EnvironmentPostProcessor

一、简介 EnvironmentPostProcessor可以在spring conetxtrefreshed之前,添加或者修改环境配置。 EnvironmentPostProcessor在实现类必须在META-INF/spring.factories中注册 启动顺序控制方式:可以实现Ordered接口,或者可以在类上增加@Order注解. EnvironmentPostProcessor接口实现代表:ConfigFileApplicationListener,其他实现:CloudFoun...

yiding123的专栏 2539

springcloud ConfigDataMissingEnvironmentPostProcessor$ImportException: No spring.config.import set

springcloud ConfigDataMissingEnvironmentPostProcessor$ImportException: No spring.config.import set

寂夜了无痕的博客 4729

EnvironmentPostProcessor实现原理解析

EnvironmentPostProcessor实现原理解析 SpringBoot2.4+是EnvironmentPostProcessorApplicationListener SpringBoot2.4以前是ConfigFileApplicationListener

bearboy80的专栏 2983

SprintBoot系列之加载application.yml文件中的配置过程

从SpringMvc开发过度到SpringBoot开发的读者一定可以感受到开发效率大大的提升,其中之一就是自动装配特性,它提供了大量的默认配置,节省了开发人员的时间成本。文章介绍的并不是自动装配的原理,而是其中关于SpringBoot是如何读取Yaml或者Properties配置文件的。要想说清楚SpringBoot如何加载Yaml配置文件,需要先了解spring.factories文件。如下图,SpringBoot的有些jar包中包含了spring.factories文件,这个文件存放了一些程序启动时需要

马各马它 2495
上一篇: Spring Cloud Config Client工作原理
下一篇: Kafka安全认证(Java)
思维的深度
博客等级 码龄11年 2万+粉丝 391原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值