SpringCloud中Bootstrap配置的生效

1. Bootstrap配置文件在什么时候才会生效?

SpringBoot 2.4.x的版本之后,对于bootstrap.properties/bootstrap.yaml配置文件(我们合起来成为Bootstrap配置文件)的支持,需要导入如下的依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
            <version>3.1.0</version>
        </dependency>

其实这个jar包里什么都没有,就只有一个标识类Marker,用来标识要开启Bootstrap配置文件的支持,至于原理是什么?我们下面逐步去进行解析

2. Bootstrap配置文件生效的原因

既然是SpringBoot,我们主要研究它的run方法,在这个方法中定义了SpringBoot启动的整个流程。

image.png

我们要研究的是Bootstrap配置文件的相关信息,就肯定和环境对象有关系,因此我们关注准备环境变量的步骤。

image.png

在这里我们可以看到,首先是创建了一个环境对象,接着,通知所有的监听器,告诉它们环境对象已经准备好了,可以开始去进行配置环境信息了。我们关心的application配置文件以及bootstrap配置文件,都是使用监听器的方式去监听环境准备好的事件时去扩展的。

对于Bootstrap的配置文件,将会被BootstrapApplicationListener去进行处理,而这个监听器,在cloud-context的jar包下通过SpringFactories的方式去进行了配置,因此在运行时,就会实例化这个监听器并在创建环境之后去进行回调。

而对于application配置文件,是由另外一个监听器(EnvironmentPostProcessorApplicationListener)去进行处理的,这个监听器里面会读取spring.config.name作为配置文件名,如果没有的话,会使用application作为默认的配置文件名。

image.png

既然它是一个监听器,那么,我们需要关注的是它的onApplicationEvent方法。

image.png

首先我们需要注意一个点,这个监听器的Order很高,一般来说,它都是第一个被回调到的监听器,因此在来到这里时,其实application配置文件并未加载到环境当中,但是命令行参数是已经被解析到环境当中了,我们上面的步骤当中已经提到过。

我们首先要关注的一个点就是bootstrapEnabled(environment),很明显,它是用来判断bootstrap是否要生效的。我们打开它的源码

image.png

我们可以看到,是否开启bootstrap,只需要满足当前环境信息当中有配置spring.cloud.bootstrap.enabled=true,或者当前的依赖当中存在有org.springframework.cloud.bootstrap.marker.Marker这个类,就会开启bootstrap

而我们上面已经说过了,导入spring-cloud-starter-bootstrap这个组件的作用就是为了让容器中存在有该标识类,我们下面点开源码来验证一下。

image.png

我们可以看到,确实只有一个Marker的标识类,其它就什么都没有了。

实际上,通过在启动参数中配置相关的属性也可以(因为Bootstrap的监听器优先级比较高,因此配置在application配置文件当中无效,application配置文件还未加载到环境当中来,所以必须在启动参数中去进行配置),不用非得导入jar包(前提容器中已经有了cloud-context的jar包,因为这个jar包当中导入了BootstrapApplicationListener组件)。

image.png

3. Bootstrap的核心代码-bootstrapServiceContext

我们继续来看BootstrapApplicationListener的后续源码中的bootstrapServiceContext方法,这个方法是整个Bootstrap的核心。

3.1 Bootstrap隔离容器的构建

image.png
image.png

我们可以看到,其实这里的主要逻辑,就是去创建一个隔离容器,这个容器中的组件是由BootstrapImportSelectorConfiguration它去进行处理的。还有一个关键点,它往自己构建的一个Map的属性源当中加入了一个配置项spring.config.namebootstrap(如果没有自己额外配置的话),这个配置项,决定的是它在运行时需要加载的配置文件的名称。

而这里其实会运行bootstrap隔离容器,因此也会有环境的监听器EnvironmentPostProcessorApplicationListener,这个组件就会读取到我们配置的spring.config.name配置项,去加载bootstrap配置文件。

image.png

其实它就是导入一个Selector,通过Selector给容器中导入组件。

image.png

而这个Selector,其实就是加载BootstrapConfiguration中配置的相关配置。

那么BootstrapConfiguration配置了什么?下面是cloud-context中配置的自动配置的组件。

image.png

通过自动配置的组件,我们可以看到其中一个肯定是关于处理占位符的组件,它主要给容器中导入一个嵌入式的值解析器,用来解析占位符。

3.2 BootstrapConfigurationPropertySourceBootstrapConfiguration

这个组件值得我们去进行关注

image.png

我们可以看到,它本身是一个ApplicationContext的初始化器,并且会自动注入Bootstrap隔离容器中配置的所有的Locator,这个Locator是实现分布式配置中心的关键。

下面我们来看Nacos-Config的源码,看看它是怎么加载ConfigServer中的配置文件的?

image.png

我们可以看到,它给Bootstrap隔离容器中导入了一个NacosConfigBootstrapConfiguration组件,我们来看这个组件的源码

image.png

我们可以看到,它给容器中导入了一个NacosConfigManager组件,包装一个ConfigService,这个组件是Nacos中用来读取远程ConfigServer中的配置信息的组件。如果使用过Nacos的API的使用的话,应该比较熟悉这个组件。

image.png

它还给容器中导入了一个Locator组件,而导入的这个Locator组件的locate方法的代码如下,我们可以很明确的看到了准备dataId,并且开始去加载配置文件,并将所有要加载的配置文件进行聚合成为一个属性源对象,并返回,Spring就会自己对其去进行处理,并导入到app容器的环境对象当中去。

image.png

我们可以知道,所有的Locator组件,都会被注入到PropertySourceBootstrapConfiguration这个组件中,但是这个组件并不会在Bootstrap隔离容器中生效,这个组件,实际上会在app容器中去生效,我们来找它的源码。

我们在BootstrapApplicationListener这个组件的onApplicationEvent方法中,可以看到有apply这个步骤。这个步骤的源码如下:

image.png

我们可以看到,它将app容器的组件和bootstrap隔离容器中的组件去进行了合并,并设置到app容器所对应的SpringApplication组件当中。

问题来了,ApplicationContext的初始化器在什么时候会被应用?

3.3 ApplicationContext的初始化器什么使用生效

我们回到SpringApplicationrun方法,找到准备Context的一个步骤。

image.png

我们可以看到,在这个方法中存在有applyInitializers这样的步骤,那就很明显了,就是在这里回调的。在创建完ApplicationContext之后,立马就回调所有的初始化器,其实根据初始化器这个名词,我们也可以大概猜到,它会在创建完ApplicationContext之后立马就会去进行回调。

image.png

3.4 对整个过程进行梳理

image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容