这些不知道,别说你熟悉 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

推荐阅读