二.SpringBoot源码之属性文件Bootstrap应用实操

2.1 Bootstrap.properties属性配置文件加载原理分析

上篇文章我们学习了SpringBoot中application.properties配置文件以及application.yml配置文件的加载原理,接下来我们就来学习关于boorstrap.properties配置文件的加载原理。小伏笔:bootstrap.properties中定义的文件信息会先与application.properties中的信息加载。

2.2 bootstrap配置文件的依赖导入使用

创建新的模块项目

spring boot 加载 yaml springboot bootstrap.yml加载原理_SpringBoot源码

因为SpringBoot中默认是不支持bootstrap.properties属性文件的。我们需要映入SpringCloud的依赖才可以。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.ljw</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
		<spring.cloud-version>Hoxton.SR5</spring.cloud-version>
	</properties>

	<dependencies>


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<version>2.2.5.snapshot</version>
		</dependency>

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

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>${spring-cloud.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

</project>

然后创建对应的bootstrap.properties文件

spring boot 加载 yaml springboot bootstrap.yml加载原理_spring boot_02

同步的我们也会创建application.properties文件,修改掉其中一个属性

spring boot 加载 yaml springboot bootstrap.yml加载原理_SpringBoot源码_03

然后我们在controller中获取测试

spring boot 加载 yaml springboot bootstrap.yml加载原理_Spring_04

访问测试:http://localhost:8080/testDemo

通过访问看到bootstrap.properties中的信息获取到了,同时age也被application.properties中的属性覆盖掉了。加载顺序到底是什么?为什么会覆盖呢?我们接下来分析。

spring boot 加载 yaml springboot bootstrap.yml加载原理_Bootstrap配置文件加载_05

三 SpringBoot源码之属性文件bootstrap加载原理分析

3.1 BootstrapApplicationListener监听器

  其实在这个依赖中会在对应的spring.factories文件中给我们提供新的监听器,也就是BootstrapApplicationListener监听器。

spring boot 加载 yaml springboot bootstrap.yml加载原理_Bootstrap配置文件加载_06

  而BootstrapApplicationListener监听触发的事件是ApplicationEnvironmentPreparedEvent事件,这个事件其实和我们前面介绍监听application.properties的时候的监听器ConfigFileApplicationListener监听的是同一个事件。

spring boot 加载 yaml springboot bootstrap.yml加载原理_Spring_07


当启动的时候发布对应的事件,该监听器会触发相关的解析行为。

spring boot 加载 yaml springboot bootstrap.yml加载原理_spring boot 加载 yaml_08

3.2 启动流程梳理

  搞清楚了监听器的关系后,我们来看下启动的流程代码具体是怎么执行的。

开始进入源码

spring boot 加载 yaml springboot bootstrap.yml加载原理_Spring_09


继续进入

spring boot 加载 yaml springboot bootstrap.yml加载原理_SpringBoot源码_10

然后进入构造方法

spring boot 加载 yaml springboot bootstrap.yml加载原理_spring boot_11

在SpringApplication的构造方法中我们要注意两点:

  1. 监听器的加载
  2. main方法的主类记录

spring boot 加载 yaml springboot bootstrap.yml加载原理_Bootstrap配置文件加载_12

然后回来进入run方法

spring boot 加载 yaml springboot bootstrap.yml加载原理_Spring_13

bootstrapApplicationListener监听器

spring boot 加载 yaml springboot bootstrap.yml加载原理_Bootstrap配置文件加载_14

Debug到第一个端点。

spring boot 加载 yaml springboot bootstrap.yml加载原理_Bootstrap配置文件加载_15

通过debug我们可以看到又进入了一次run方法。先看处理的结果。

spring boot 加载 yaml springboot bootstrap.yml加载原理_SpringBoot源码_16

然后我们再放过,继续

spring boot 加载 yaml springboot bootstrap.yml加载原理_Spring_17

分两次加载,有先有后。先加载bootstrap.properties,然后再次加载application.properties配置文件。那么这里面的第一个加载的原理到底是什么呢?继续来分析。

3.3 bootstrap.properties的加载原理

  接下来看看是如果出现的一个父context来优先加载我们的bootstrap.properteis文件的

spring boot 加载 yaml springboot bootstrap.yml加载原理_Spring_18


链路追踪过程

spring boot 加载 yaml springboot bootstrap.yml加载原理_Bootstrap配置文件加载_19

进入到BootstrapApplicationListener中来看。

spring boot 加载 yaml springboot bootstrap.yml加载原理_spring boot_20

然后进入到 bootstrapServiceContext方法中。

spring boot 加载 yaml springboot bootstrap.yml加载原理_SpringBoot源码_21

这儿我们看到有创建了一个SpringApplication对象。这个其实就是父Context对象了。

spring boot 加载 yaml springboot bootstrap.yml加载原理_SpringBoot源码_22

进入run方法你会发现,回到了前面

spring boot 加载 yaml springboot bootstrap.yml加载原理_spring boot 加载 yaml_23

spring boot 加载 yaml springboot bootstrap.yml加载原理_Spring_24