spring boot(2.4.x 开始)和spring cloud项目中配置文件application和bootstrap加载顺序

在前面的文章基础上

https://blog.csdn.net/zlpzlpzyd/article/details/136060312

spring boot 2.4.x 版本之前通过 ConfigFileApplicationListener 加载配置

https://github.com/spring-projects/spring-boot/blob/v2.3.12.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/package-info.java

从 spring boot 2.4.x 开始,ConfigFileApplicationListener 标记为已过期,监听替换为BootstrapConfigFileApplicationListener(继承了 ConfigFileApplicationListener 作为过渡),用 ConfigDataEnvironmentPostProcessor (EnvironmentPostProcessor 的实现类)代替用于加载配置,从这个版本开始 ConfigFileApplicationListener 在 spring.factories 文件中搜不到。

EnvironmentPostProcessor 的加载通过接口 EnvironmentPostProcessorsFactory 的实现类 ReflectionEnvironmentPostProcessorsFactory 来完成,在需要对应的 bean 时调用 EnvironmentPostProcessorsFactory#getEnvironmentPostProcessors() 通过反射功能来实现。

在此版本中专门重写了文件加载相关的功能。全部类位于如下 package。

https://github.com/spring-projects/spring-boot/blob/v2.4.0/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/package-info.java

子容器通过 BootstrapApplicationListener 加载 bootstrap 配置文件转换为 OriginTrackedMapPropertySource 类型

spring boot(2.4.x 开始)和spring cloud项目中配置文件application和bootstrap加载顺序_第1张图片

在父容器中转换为名为 springCloudDefaultProperties 的配置对象,将子容器中的配置添加到其中。

spring boot(2.4.x 开始)和spring cloud项目中配置文件application和bootstrap加载顺序_第2张图片

从 spring boot 2.4.0 到 2.4.2 之前的版本中有一个问题,同样的配置都在 yml 和 properties 中存在,则 yml 中的优先,实际验证正是如此。

但是从 spring boot 2.4.2 开始又改回了默认顺序。

官网文档建议使用配置的话最好使用一种,不要两种混用。


	org.springframework.cloud
	spring-cloud-starter-bootstrap

bootstrap 相关加载需要单独处理

https://github.com/spring-cloud/spring-cloud-commons/tree/v2.2.9.RELEASE/spring-cloud-context/src/main/java/org/springframework/cloud/util

从 spring-cloud-commones 3.x 开始,添加了单独判断 org.springframework.cloud.bootstrap.marker.Marker 的工具类,但是这个需要单独引入,如下


	org.springframework.cloud
	spring-cloud-starter-bootstrap

https://github.com/spring-cloud/spring-cloud-commons/tree/v3.0.0/spring-cloud-context/src/main/java/org/springframework/cloud/util

添加了两个注解和工具类 PropertyUtils 用于判断当前项目是否能调用 BootstrapApplicationListener 中的逻辑进行子容器执行。

spring boot(2.4.x 开始)和spring cloud项目中配置文件application和bootstrap加载顺序_第3张图片

在 spring-cloud-commones 4.0.0 中将 ConfigFileApplicationListener 中的逻辑添加到 BootstrapConfigFileApplicationListener 中,不再继承 ConfigFileApplicationListener。

public abstract class PropertyUtils {

	/**
	 * Property name for checking if bootstrap is enabled.
	 */
	public static final String BOOTSTRAP_ENABLED_PROPERTY = "spring.cloud.bootstrap.enabled";

	/**
	 * Property name for spring boot legacy processing.
	 */
	public static final String USE_LEGACY_PROCESSING_PROPERTY = "spring.config.use-legacy-processing";

	/**
	 * Property name for bootstrap marker class name.
	 */
	public static final String MARKER_CLASS = "org.springframework.cloud.bootstrap.marker.Marker";

	/**
	 * Boolean if bootstrap marker class exists.
	 */
	public static final boolean MARKER_CLASS_EXISTS = markerClassExists();

	private static boolean markerClassExists() {
		try {
			ClassUtils.forName(MARKER_CLASS, null);
			return true;
		}
		catch (ClassNotFoundException e) {
			return false;
		}
	}

	private PropertyUtils() {

	}

	public static boolean bootstrapEnabled(Environment environment) {
		return environment.getProperty(BOOTSTRAP_ENABLED_PROPERTY, Boolean.class, false) || MARKER_CLASS_EXISTS;
	}

	public static boolean useLegacyProcessing(Environment environment) {
		return environment.getProperty(USE_LEGACY_PROCESSING_PROPERTY, Boolean.class, false);
	}

}

未指定参数 spring.cloud.bootstrap.enabled=true 或者 MARKER_CLASS 在类路径中不存在的情况下,返回 false。
未指定参数 spring.config.use-legacy-processing=true 的情况下,返回 false。

if (!bootstrapEnabled(environment) && !useLegacyProcessing(environment)) {
    return;
}

鉴于值都为 false,所以 BootstrapApplicationListener 中逻辑无法执行,即 bootstrap 相关配置无法加载。

所以,只要其中一个不为 false 即可。

如果想要加载 bootstrap 中的配置,有两种方式,任意一种都可

方式1

在 pom.xml 中添加依赖


    org.springframework.cloud
    spring-cloud-starter-bootstrap

方式2

在启动时添加 vm 参数

spring.cloud.bootstrap.enabled=true

从 spring boot 3 开始 ConfigFileApplicationListener 移除。其中的代码逻辑迁移到 BootstrapConfigFileApplicationListener 中,不再继承 ConfigFileApplicationListener 。

你可能感兴趣的:(spring,java,spring,boot,spring,cloud,spring,java)