交流
商城
MCN
登入
注册
首页
提问
分享
讨论
建议
公告
动态
发表新帖
发表新帖
nacos统一配置中心 第1 章:加载 PropertySourceBootstrapConfiguration
分享
未结
0
1570
李延
LV6
2021-06-18
悬赏:20积分
# 初始化 在spring-cloud-context包中我们看到下面的配置  其中BootstrapConfiguration是spring-cloud的父上下文,所以只有当我们设置 ```java --spring.cloud.bootstrap.enabled=true ``` 是PropertySourceBootstrapConfiguration才会被加载。 我们具体看一下合格类 # PropertySourceBootstrapConfiguration 在这个类中有成员变量,通过spring注入: ```java @Autowired(required = false) private List<PropertySourceLocator> propertySourceLocators = new ArrayList<>(); ``` 而后继承自ApplicationContextInitializer类,这个是在创建完成context后刷新context前执行它的initialize方法。 ==注意:== PropertySourceBootstrapConfiguration对象的定义是在刷新上下文过程中被加载到spring中,此时已经过了父上下文执行的事件。但父上下文会把自己的Initializer对象传递给子上下文,所以这个类定义加载是在父上下文中,但执行方法是在子上下文中。 我们具体看一下这个方法: ```java @Override public void initialize(ConfigurableApplicationContext applicationContext) { List<PropertySource<?>> composite = new ArrayList<>(); //对propertySourceLocators排序 AnnotationAwareOrderComparator.sort(this.propertySourceLocators); boolean empty = true; ConfigurableEnvironment environment = applicationContext.getEnvironment(); //变量每个值 for (PropertySourceLocator locator : this.propertySourceLocators) { //通过locateCollection获取到他的配置变量 Collection<PropertySource<?>> source = locator.locateCollection(environment); if (source == null || source.size() == 0) { continue; } List<PropertySource<?>> sourceList = new ArrayList<>(); for (PropertySource<?> p : source) { if (p instanceof EnumerablePropertySource) { EnumerablePropertySource<?> enumerable = (EnumerablePropertySource<?>) p; sourceList.add(new BootstrapPropertySource<>(enumerable)); } else { sourceList.add(new SimpleBootstrapPropertySource(p)); } } logger.info("Located property source: " + sourceList); composite.addAll(sourceList); empty = false; } if (!empty) { MutablePropertySources propertySources = environment.getPropertySources(); String logConfig = environment.resolvePlaceholders("${logging.config:}"); LogFile logFile = LogFile.get(environment); for (PropertySource<?> p : environment.getPropertySources()) { if (p.getName().startsWith(BOOTSTRAP_PROPERTY_SOURCE_NAME)) { propertySources.remove(p.getName()); } } //将刚获取到的配置变量添加到环境中。 insertPropertySources(propertySources, composite); reinitializeLoggingSystem(environment, logConfig, logFile); setLogLevels(applicationContext, environment); handleIncludedProfiles(environment); } } ``` 通过上面代码我们看到 1. 通过spring注入PropertySourceLocator对象。 2. 并且通过PropertySourceLocator对象的locateCollection方法获取到配置变量。 3. 将刚获取到的配置变量加载到environment中。 我们看到配置变量的获取过程是交给了PropertySourceLocator对象,而这个类只负责将获取到的变量添加到environment中。 ## insertPropertySources 这一步是将获取到的对象添加至environment中,我们重点关注的是添加后环境变量的优先级;我们看一下这部分代码 ```java PropertySourceBootstrapProperties remoteProperties = new PropertySourceBootstrapProperties(); Binder.get(environment(incoming)).bind("spring.cloud.config", Bindable.ofInstance(remoteProperties)); if (!remoteProperties.isAllowOverride() || (!remoteProperties.isOverrideNone() && remoteProperties.isOverrideSystemProperties())) { for (PropertySource<?> p : reversedComposite) { propertySources.addFirst(p); } return; } if (remoteProperties.isOverrideNone()) { for (PropertySource<?> p : composite) { propertySources.addLast(p); } return; } ``` 我们看到这部分是通过PropertySourceBootstrapProperties对象实现的,而PropertySourceBootstrapProperties对象又是spring.cloud.config变量。 我们看一下这几个变量的注释就明白它们的逻辑了: ```java /** * Flag to indicate that the external properties should override system properties. * Default true. 标志以指示外部属性应覆盖系统属性。 默认为真 */ private boolean overrideSystemProperties = true; /** * Flag to indicate that {@link #isOverrideSystemProperties() * systemPropertiesOverride} can be used. Set to false to prevent users from changing * the default accidentally. Default true. 指示可以使用systemPropertiesOverride标志。 设置为 false 以防止用户意外更改默认值。 默认为真。 */ private boolean allowOverride = true; /** * Flag to indicate that when {@link #setAllowOverride(boolean) allowOverride} is * true, external properties should take lowest priority and should not override any * existing property sources (including local config files). Default false. 标志以指示当allowOverride为 true 时,外部属性应具有最低优先级,并且不应覆盖任何现有的属性源(包括本地配置文件)。 默认为假 */ private boolean overrideNone = false; ``` 所以默认情况下外部变量会被优先加载 # 总结 对于统一配置中心只有当配置 --spring.cloud.bootstrap.enabled=true时才会生效。 并且其会再父上下文中优先加载。 默认情况下系统外部加载的变量优先度会高于内部系统。 spring-cloud 只负责将获取到的变量加载至环境中,而具体的便利获取过程交给PropertySourceLocator来处理。 我们只需要将自己的PropertySourceLocator对象添加到父上下文中,spring就会自动加载我们指定的变量。
回帖
消灭零回复
提交回复
热议榜
java 相关知识分享
8
好的程序员与不好的程序员
6
写给工程师的十条精进原则
5
spring boot以jar包运行配置的logback日志文件没生成
5
一步一步分析SpringBoot启动源码(一)
5
MockMvc测试
5
【吐槽向】是不是有个吐槽的板块比较好玩
4
logstash jdbc同步mysql多表数据到elasticsearch
3
IntelliJ IDEA 优质License Server
3
.gitignore忽略规则
3
SpringBoot启动源码分析
3
一步一步分析SpringBoot启动源码(三)
3
2
一步一步分析SpringBoot启动源码(二)
2
积分不够将无法发表新帖
2
官方产品
Meta-Boot - 基于MCN
MCN - 快速构建SpringBoot应用
微信扫码关注公众号