spring cloud config server源碼學習(一)

文章目錄

  • 1. 注解EnableConfigServer
  • 2. ConfigServerAutoConfiguration
    • 2.1 @ConditionalOnBean和@ConditionalOnProperty
    • 2.2 @Import注解
      • 2.2.1. EnvironmentRepositoryConfiguration.class
      • 2.2.2. CompositeConfiguration.class
      • 2.2.3. ResourceRepositoryConfiguration.class
      • 2.2.4. ConfigServerEncryptionConfiguration.class
      • 2.2.5. ConfigServerMvcConfiguration.class
      • 2.2.6. ResourceEncryptorConfiguration.class
  • 3. EnvironmentRepository
  • 4. EnvironmentRepositoryConfiguration.class
  • 5. rest接口

spring cloud config server 作為一個spring boot工程,到底是如何運行起來的?似乎如上一篇文章中那樣,引入了starter,啟動了注解,配置了git的信息,就可以獲取到數據了。那具體的原理是什么呢?

1. 注解EnableConfigServer

@EnableConfigServer
@SpringBootApplication
@EnableDiscoveryClient
public class ConfigServer {public static void main(String[] args) {SpringApplication.run(ConfigServer.class, args);}
}

可以看到啟動類上加入注解@EnableConfigServer。我們查看該注解的源碼:

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

這個注解的定義當中,通過Import注解加載Bean ConfigServerConfiguration.class

@Configuration(proxyBeanMethods = false)
public class ConfigServerConfiguration {@Beanpublic Marker enableConfigServerMarker() {return new Marker();}class Marker {}}

這個Configuration類只是加載了一個 Bean Marker。
這是spring加載Bean的一種常用方式。

2. ConfigServerAutoConfiguration

在spring cloud config Server的jar中,org.springframework.boot.autoconfigure.AutoConfiguration.imports文件內包含了多個自動配置的類,其中就包括ConfigServerAutoConfiguration類。

org.springframework.cloud.config.server.bootstrap.ConfigServerBootstrapOverridesAutoConfiguration
org.springframework.cloud.config.server.config.ConfigServerAutoConfiguration
org.springframework.cloud.config.server.config.RsaEncryptionAutoConfiguration
org.springframework.cloud.config.server.config.DefaultTextEncryptionAutoConfiguration
org.springframework.cloud.config.server.config.EncryptionAutoConfiguration
org.springframework.cloud.config.server.config.VaultEncryptionAutoConfiguration

根據命名,可以看到各個自動配置類的功能,是啟用bootstrap配置還是啟用RSA加密等等。這里暫時先關注
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、@ConditionalOnProperty和@Import。

2.1 @ConditionalOnBean和@ConditionalOnProperty

當這兩個注解出現在同一個類上的時候,兩個Conditional條件必須同時滿足,即ConfigServerConfiguration.Marker.class這個Bean存在的同時,還要滿足Spring環境屬性中存在 ConfigServerProperties.PREFIX + “.enabled” 屬性且其值為 true,或者該屬性缺失(由于 matchIfMissing = true)。這個PREFIX是spring.cloud.config.server。
這里剛好好上面通過@EnableConfigServer加載的Bean Marker.class呼應上。

2.2 @Import注解

Import注解引入了六個類要加載到spring context中。

2.2.1. EnvironmentRepositoryConfiguration.class

EnvironmentRepositoryConfiguration 是Spring Cloud Config Server中配置存儲庫的核心配置類。它負責創建和配置EnvironmentRepository實例,EnvironmentRepository用于從各種后端(如Git、SVN、本地文件系統等)獲取配置屬性。

定義和配置不同類型的EnvironmentRepository(如GitEnvironmentRepository、NativeEnvironmentRepository)。
通過注入不同的配置屬性,來靈活配置不同類型的存儲庫。

2.2.2. CompositeConfiguration.class

CompositeConfiguration 負責配置和管理CompositeEnvironmentRepository。CompositeEnvironmentRepository允許將多個EnvironmentRepository組合在一起,以便從多個源獲取配置。

配置CompositeEnvironmentRepository,將多個EnvironmentRepository實例組合成一個邏輯上的存儲庫。
提供從多個配置源合并配置屬性的功能,以實現更復雜的配置管理場景。

2.2.3. ResourceRepositoryConfiguration.class

ResourceRepositoryConfiguration 負責配置與管理資源存儲庫(ResourceRepository)。ResourceRepository用于訪問和管理配置服務器上的靜態資源,如配置文件、密鑰等。

配置不同類型的ResourceRepository,如文件系統資源存儲庫或Git資源存儲庫。
通過REST接口提供資源訪問和管理功能。

2.2.4. ConfigServerEncryptionConfiguration.class

ConfigServerEncryptionConfiguration 負責配置加密和解密功能。它提供加密和解密配置屬性的能力,確保敏感數據在傳輸和存儲時得到保護。

配置加密器(TextEncryptor),用于加密和解密敏感配置信息。
提供加密和解密端點,允許客戶端通過API進行加密和解密操作。

2.2.5. ConfigServerMvcConfiguration.class

ConfigServerMvcConfiguration 配置Spring MVC相關的組件,為Spring Cloud Config Server提供RESTful API。它定義了Config Server的主要控制器和路由。

定義Config Server的REST API端點,處理配置屬性的請求。
配置HTTP請求處理、路由和控制器。

2.2.6. ResourceEncryptorConfiguration.class

ResourceEncryptorConfiguration 負責配置與資源加密相關的功能。它確保資源存儲庫中的敏感數據在存儲和訪問時得到加密保護。

配置用于資源加密和解密的組件。
提供加密資源的支持,確保靜態資源的安全性。

3. EnvironmentRepository

對于 Spring Cloud Config 而言,它把所有的配置信息抽象為一種 Environment(環境),而存儲這些配置信息的地方就稱為 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中把配置信息抽象為application,profile和label三個維度來管理,即哪一個應用application在什么樣的環境profile下,使用哪一個label的配置數據。

4. EnvironmentRepositoryConfiguration.class

這個類里加載很多的內容,包括svn、git、jdbc等等的RepositoryConfiguration。其中有一個Configuration類是DefaultRepositoryConfiguration.class。這個是放在最后一個加載的配置,即默認的配置:

@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(value = EnvironmentRepository.class, search = SearchStrategy.CURRENT)
class DefaultRepositoryConfiguration {@Beanpublic MultipleJGitEnvironmentRepository defaultEnvironmentRepository(MultipleJGitEnvironmentRepositoryFactory gitEnvironmentRepositoryFactory,MultipleJGitEnvironmentProperties environmentProperties) throws Exception {return gitEnvironmentRepositoryFactory.build(environmentProperties);}}

這里是加載MultipleJGitEnvironmentRepository的Bean,由gitEnvironmentRepositoryFactory的build方法來構建:

public MultipleJGitEnvironmentRepository build(MultipleJGitEnvironmentProperties environmentProperties)throws Exception {if (this.connectionFactory.isPresent()) {HttpTransport.setConnectionFactory(this.connectionFactory.get());this.connectionFactory.get().addConfiguration(environmentProperties);}MultipleJGitEnvironmentRepository repository = new MultipleJGitEnvironmentRepository(this.environment,environmentProperties, ObservationRegistry.NOOP);repository.setTransportConfigCallback(transportConfigCallbackFactory.build(environmentProperties));if (this.server.getDefaultLabel() != null) {repository.setDefaultLabel(this.server.getDefaultLabel());}repository.setGitCredentialsProviderFactory(gitCredentialsProviderFactory);repository.getRepos().forEach((name, repo) -> repo.setGitCredentialsProviderFactory(gitCredentialsProviderFactory));return repository;}

而DefaultRepositoryConfiguration這個類,被GitRepositoryConfiguration繼承了。

@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 等具體某一種配置倉庫的實現方式,最終我們處理的對象都是位于本地文件系統中的配置文件。

請添加圖片描述
在AbstractScmEnvironmentRepository類中

@Overridepublic synchronized Environment findOne(String application, String profile, String label) {return findOne(application, profile, label, false);}@Overridepublic synchronized Environment findOne(String application, String profile, String label, boolean includeOrigin) {NativeEnvironmentRepository delegate = new NativeEnvironmentRepository(getEnvironment(),new NativeEnvironmentProperties(), this.observationRegistry);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());}

在上面的findOne方法中,調用了NativeEnvironmentRepository類的findOne方法:

@Overridepublic 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() {@Overridepublic 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(ObservationEnvironmentRepositoryWrapper.wrap(this.observationRegistry, 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的更新。

5. rest接口

Server端獲取到了數據,是通過rest接口來提供給client的。這里EnvironmentController提供了rest接口:

@GetMapping(path = "/{name}/{profiles:(?!.*\\b\\.(?:ya?ml|properties|json)\\b).*}",produces = MediaType.APPLICATION_JSON_VALUE)public Environment defaultLabel(@PathVariable String name, @PathVariable String profiles) {return getEnvironment(name, profiles, null, false);}@GetMapping(path = "/{name}/{profiles:(?!.*\\b\\.(?:ya?ml|properties|json)\\b).*}",produces = EnvironmentMediaType.V2_JSON)public Environment defaultLabelIncludeOrigin(@PathVariable String name, @PathVariable String profiles) {return getEnvironment(name, profiles, null, true);}@GetMapping(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);}@GetMapping(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);}

這里要注意path路徑的配置,在類注解上有@RequestMapping(method = RequestMethod.GET, path = “${spring.cloud.config.server.prefix:}”)可以配置前綴,不配置的話就是默認值“”。
在方法上的路徑,是/name/profile/label。這個正是配置文件中配置的內容。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/15076.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/15076.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/15076.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python3 + selenium webdriver自動化測試啟動不同瀏覽器

selenium webdriver自動化測試啟動不同瀏覽器 selenium webdriver 介紹Selenium WebDriver 進行自動化測試的一般流程瀏覽器驅動下載瀏覽器驅動的安裝chrome、edge、Firefox、Opera、Safari、phantomjs 應用Headless Chrome 、Headless Firefox 應用 selenium webdriver 介紹 …

shell命令運行原理及Linux權限問題

目錄 shell命令以及運行原理用戶管理添加用戶刪除用戶sudo Linux權限的概念Linux權限管理文件訪問者的分類&#xff08;人&#xff09;文件類型和訪問權限&#xff08;事物屬性&#xff09;文件權限值的表示方法文件訪問權限的相關設置方法 目錄的權限粘滯位 shell命令以及運行…

備考AMC8和AMC10競賽,吃透2000-2024年1850道真題和解析(持續)

多做真題&#xff0c;吃透真題和背后的知識點是備考AMC8、AMC10有效的方法之一&#xff0c;通過做真題&#xff0c;可以幫助孩子找到真實競賽的感覺&#xff0c;而且更加貼近比賽的內容&#xff0c;可以通過真題查漏補缺&#xff0c;更有針對性的補齊知識的短板。 今天我們繼續…

PostgreSQL基本使用Schema

參考文章&#xff1a;PostgreSQL基本使用&#xff08;3&#xff09;Schema_pg數據庫查詢schema-CSDN博客 PostgreSQL 模式&#xff08;Schema&#xff09;可以理解為是一個表的集合&#xff08;或者所屬者&#xff09;。 例如&#xff1a;在 MySQL 中&#xff0c;Scheam 是庫&…

gcc源碼分析(AST抽象語法樹)

文章目錄 三、AST相關1、AST(抽象語法樹)1.1 樹結點的聲明1.2 樹結點的結構1.2.1 tree_node聯合體1.2.2 tree_base結構體1.2.3 tree_common結構體1.2.4 常量結構體1.2.5 **標識符節點**2、符號綁定,作用域與block樹節點2.1 lang_identifier結構體2.2 c_binding結構體2.3 scop…

HLS視頻加密,讓您的視頻內容更安全!

背景介紹 HLS視頻加密是一種基于HTTP Live Streaming&#xff08;HLS&#xff09;協議的加密技術。它的核心思想是將視頻切片進行加密處理&#xff0c;在客戶端播放時需要先獲取解密密鑰才能正常偶發。通過這種方式&#xff0c;HLS加密可以有效防止未經授權的第三方竊取視頻內…

測試短信推薦參考

短信測試參考 國外&#xff1a; smstome 支持多個國家號碼 官網地址&#xff1a; https://smstome.com/ quackr.io 支持多個國家號碼 官網地址&#xff1a; https://quackr.io/ receive-smss 支持多個國家號碼 地址&#xff1a; https://receive-smss.com/ receive-sms-fr…

C#字典的常用方法

C#的字典&#xff08;Dictionary&#xff09;類是一個通用的集合類&#xff0c;它實現了鍵值對的存儲和訪問。以下是一些常用的字典方法&#xff1a; Add(key, value)&#xff1a;向字典中添加一個指定的鍵值對。Remove(key)&#xff1a;從字典中移除具有指定鍵的元素。Contai…

LLM大模型的7種推理框架分析

LLM的7種推理框架 Hugging Face的transformers 這是一個Python庫&#xff0c;可以簡化本地運行LLM的過程。 Transformers的優點&#xff1a; 自動模型下載提供代碼片段非常適合實驗和學習 Transformers的缺點&#xff1a; 需要對ML和NLP有深入了解需要編碼和配置技能 2.L…

深度學習之基于Tensorflow低光增強的深層Retinex分解

歡迎大家點贊、收藏、關注、評論啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代碼。 文章目錄 一項目簡介 二、功能三、系統四. 總結 一項目簡介 一、項目背景與意義 在圖像處理領域&#xff0c;低光照環境下的圖像增強是一個具有挑戰性的問題。為了提高圖像的可…

紐曼新品X1000:輕巧便攜僅重9.9公斤的1度電應急電源

在戶外救援行動和應急設備中&#xff0c;電力供應的穩定性和安全性直接影響到救援工作的效率和成功率。在現代救援工作中&#xff0c;常見的光學聲波探測儀、通信聯絡設備、氣象檢測儀、生命探測儀、照明設備等裝備均需有持續的電力供應&#xff0c;才能保障救援工作的有序開展…

西門子WINCC8.0VBS腳本學習講解

WinCC VBS腳本置位/復位/取反 二進制變量 "TAG1_BOOL1" 進行置位復位取反操作 步驟&#xff1a;按鈕-->對象屬性-->事件-->單擊鼠標VBS動作填入代碼如下: 對二進制變量進行復位 對二進制變量進行置位 對二進制變量進行取反 VBS腳本數學運算/讀寫批處理 …

第十六講:數據在內存中的存儲

第十六講&#xff1a;數據在內存中的存儲 1.整數在內存中的存儲1.1存儲方式1.2大小端字節序1.3大小端字節序排序規則1.4為什么要有大小端1.5練習1.5.1練習11.5.2練習21.5.3練習31.5.4練習41.5.5練習51.5.6練習61.5.7練習7 2.浮點數在內存中的存儲2.1練習2.2浮點數的存儲2.3浮點…

如何將數據從一部手機傳輸到另一部手機[安全快速]

概括 手機之間無需使用藍牙即可傳輸文件&#xff0c;配合專業的文件傳輸工具更高效。本文將向您介紹幾種使用不同的數據傳輸工具快速安全地將數據從一部手機傳輸到另一部手機的方法&#xff0c;特別是當有大文件或大量文件時。現在&#xff0c;我們來看看。 需要在朋友或家人之…

Rust 賦能前端 -- 寫一個 File 轉 Img 的功能

所有耀眼的成績,都需要苦熬,熬得過,出眾;熬不過,出局 大家好,我是柒八九。一個專注于前端開發技術/Rust及AI應用知識分享的Coder 此篇文章所涉及到的技術有 Rustwasm-bindgen/js-sys/web-sysWeb WorkerWebAssemblyWebpack/Vite配置WebAssemblyOffscreenCanvas腳手架生成項…

校園二手書交易|基于SprinBoot+vue的校園二手書交易管理系統(源碼+數據庫+文檔)

校園二手書交易管理系統 目錄 基于SprinBootvue的校園二手書交易管理系統 一、前言 二、系統設計 三、系統功能設計 1系統功能模塊 2管理員功能模塊 3 賣家用戶功能模塊 4 用戶功能模塊 四、數據庫設計 五、核心代碼 六、論文參考 七、最新計算機畢設選題推薦 八…

Linux:iptables防火墻部署優化之連接轉移(目的地地址轉化)

Linux&#xff1a;iptables防火墻部署優化之連接轉移&#xff08;目的地地址轉化&#xff09; 文章目錄 Linux&#xff1a;iptables防火墻部署優化之連接轉移&#xff08;目的地地址轉化&#xff09;node1操作檢測ip情況關閉firewalld防火墻服務&#xff0c;并鎖定該服務開啟ip…

什么是分布式會話

分布式會話是指在分布式系統中實現用戶會話管理的一種機制。在傳統的單服務器架構中&#xff0c;用戶的會話數據通常存儲在單個服務器或應用服務器的內存中。然而&#xff0c;隨著業務的發展和用戶量的增加&#xff0c;單服務器架構往往無法滿足高可用性和高并發的需求&#xf…

Minio WebUploader上傳文件的高級用法之進度條顯示、文件過濾、圖片預覽、圖片壓縮

系列文章目錄 第十章 Minio WebUploader上傳文件的高級用法之進度條顯示、文件過濾、圖片預覽、圖片壓縮 Minio WebUploader上傳文件的高級用法之進度條顯示、文件過濾、圖片預覽、圖片壓縮 系列文章目錄進度條顯示文件過濾圖片預覽圖片壓縮 進度條顯示 使用進程文件上傳時&a…

基于springboot+html的二手交易平臺(附源碼)

基于springboothtml的二手交易平臺 介紹部分界面截圖如下聯系我 介紹 本系統是基于springboothtml的二手交易平臺&#xff0c;數據庫為mysql&#xff0c;可用于畢設或學習&#xff0c;附數據庫 部分界面截圖如下 聯系我 VX&#xff1a;Zzllh_