這些不知道,別說你熟悉 Spring( 四 )


這些不知道,別說你熟悉 Spring

文章插圖
initialize 方法根據注入的 PropertySourceLocator 進行配置的定位獲取,獲取到的配置封裝成 PropertySource 對象,然后添加到 Spring 環境 Environment 中 。
這些不知道,別說你熟悉 Spring

文章插圖
Nacos、Zookeeper、Consul 都有提供相應 PropertySourceLocator 的實現
這些不知道,別說你熟悉 Spring

文章插圖
我們來分析下 Nacos 提供的 NacosPropertySourceLocator , locate 方法只提取了主要流程代碼,可以看到 Nacos 啟動會加載以下三種配置文件,也就是我們在 bootstrap.yml 文件里配置的擴展配置 extension-configs、共享配置 shared-configs 以及應用自己的配置,加載到配置文件后會封裝成 NacosPropertySource 放到 Spring 的 Environment 中 。
這些不知道,別說你熟悉 Spring

文章插圖
public PropertySource<?> locate(Environment env) {loadSharedConfiguration(composite);loadExtConfiguration(composite);loadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env);return composite; }loadApplicationConfiguration 加載應用配置時 , 同時會加載以下三種配置,分別是
  1. 不帶擴展名后綴,application
  2. 帶擴展名后綴 , application.yml
  3. 帶環境,帶擴展名后綴,application-prod.yml
并且從上到下,優先級依次增高
private void loadApplicationConfiguration(CompositePropertySource compositePropertySource, String dataIdPrefix,NacosConfigProperties properties, Environment environment) {String fileExtension = properties.getFileExtension();String nacosGroup = properties.getGroup();// load directly once by defaultloadNacosDataIfPresent(compositePropertySource, dataIdPrefix, nacosGroup,fileExtension, true);// load with suffix, which have a higher priority than the defaultloadNacosDataIfPresent(compositePropertySource,dataIdPrefix + DOT + fileExtension, nacosGroup, fileExtension, true);// Loaded with profile, which have a higher priority than the suffixfor (String profile : environment.getActiveProfiles()) {String dataId = dataIdPrefix + SEP1 + profile + DOT + fileExtension;loadNacosDataIfPresent(compositePropertySource, dataId, nacosGroup,fileExtension, true);} }加載過程中,通過 namespace, dataId, group 唯一定位一個配置文件
  1. 首先獲取本地緩存的配置,如果有直接返回
  2. 如果步驟1從本地沒找到相應配置文件,開始從遠處拉去,Nacos 2.0 以上版本使用 Grpc 協議進行遠程通信,1.0 及以下使用 Http 協議進行遠程通信
  3. 對拉去到的字符串進行解析,封裝成 NacosPropertySource 返回
具體細節就不展開講了 , 可以自己看源碼了解
Zookeeper、Consul 的接入也是非常簡單,可以自己分析一遍 。如果我們有自研的配置中心,需要在 SpringCloud 環境下使用 , 可以根據 SpringCloud 提供的這些擴展參考以上幾種實現快速的寫個 starter 進行接入 。
總結本篇文章主要講了下 Spring SPI 機制、SpringBoot 自動裝配原理,以及擴展點 ApplicationContextInitializer 在集成配置中心時的應用 。篇幅有限,一些具體代碼細節就沒展開講了,以后會出些文章針對某一個點進行詳細講解 。
個人開源項目DynamicTp 是一個基于配置中心實現的輕量級動態線程池管理工具 , 主要功能可以總結為動態調參、通知報警、運行監控、三方包線程池管理等幾大類 。
這些不知道,別說你熟悉 Spring

文章插圖
目前累計 2k star , 代碼優雅,使用了大量設計模式,如果你覺得看這些大型框架源碼費勁,那么可以嘗試從 DynamicTp 源碼入手,歡迎大家了解試用
官網:https://dynamictp.cn
gitee地址:https://gitee.com/dromara/dynamic-tp
github地址:https://github.com/dromara/dynamic-tp

推薦閱讀