原因
SpringBoot项目,只会识别application.* 配置文件,并不会自动识别bootstrap.yml。
bootstrap.yml配置是SpringCloud项目才会用到的,如果你想在springboot项目中用bootstrap.yml,那么你需要添加bootstrap启动器。
从Spring Boot 2.4版本开始,配置文件加载方式进行了重构。官方说明:https://docs.spring.io/spring-cloud-config/docs/current/reference/html/#config-first-bootstrap
官方文档:
39.2. Config First Bootstrap
To use the legacy bootstrap way of connecting to Config Server, bootstrap must be enabled via a property or the spring-cloud-starter-bootstrap starter. The property is spring.cloud.bootstrap.enabled=true. It must be set as a System Property or environment variable.
优先级问题
由于SpringCloud是基于SpringBoot构建的,所有SpringCloud项目两种文件都会识别,这个时候才有优先级的说法,SpringCloud项目是会优先读取bootstrap配置在读取application配置。
SpringCloud应用是基于bootstrap的上下文运行的。
源码分析
源码调试发现问题出在SpringBoot2.4.3 在SpringApplication.prepareEnvironment() 这个方法中,environment.getProperty()
SpringBoot 2.3.12RELEASE
package org.springframework.cloud.bootstrap;/**
* A listener that prepares a SpringApplication (e.g. populating its Environment) by
* delegating to {@link ApplicationContextInitializer} beans in a separate bootstrap
* context. The bootstrap context is a SpringApplication created from sources defined in
* spring.factories as {@link BootstrapConfiguration}, and initialized with external
* config taken from "bootstrap.properties" (or yml), instead of the normal
* "application.properties".
*
* @author Dave Syer
*
*/
public class BootstrapApplicationListener
implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
/**
* Property source name for bootstrap.
*/
public static final String BOOTSTRAP_PROPERTY_SOURCE_NAME = "bootstrap";
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
if (!environment.getProperty("spring.cloud.bootstrap.enabled", Boolean.class, true)) {
return;
}
// 代码省略
}
SpringBoot 2.4.3
package org.springframework.cloud.util;
import org.springframework.core.env.Environment;
import org.springframework.util.ClassUtils;
public abstract class PropertyUtils {
public static final String BOOTSTRAP_ENABLED_PROPERTY = "spring.cloud.bootstrap.enabled";
public static final String USE_LEGACY_PROCESSING_PROPERTY = "spring.config.use-legacy-processing";
public static final String MARKER_CLASS = "org.springframework.cloud.bootstrap.marker.Marker";
public static final boolean MARKER_CLASS_EXISTS = ClassUtils.isPresent("org.springframework.cloud.bootstrap.marker.Marker", (ClassLoader)null);
private PropertyUtils() {
throw new UnsupportedOperationException("unable to instatiate utils class");
}
public static boolean bootstrapEnabled(Environment environment) {
return (Boolean)environment.getProperty("spring.cloud.bootstrap.enabled", Boolean.class, false) || MARKER_CLASS_EXISTS;
}
public static boolean useLegacyProcessing(Environment environment) {
return (Boolean)environment.getProperty("spring.config.use-legacy-processing", Boolean.class, false);
}
}
解决方法
1:添加bootstrap启动器:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
2:启动参数设置
IDEA设置环境参数:select Run/Debug Configurations > Override parameters 中添加 spring.cloud.bootstrap.enabled 值为true。
命令行:java -jar -Dspring.cloud.bootstrap.enabled=true test.jar
3:项目启动类新增系统变量
spring.cloud.bootstrap.enabled=true
@EnableDiscoveryClient
@SpringBootApplication
public class Application {
public static voidSystem.setProperty("spring.cloud.bootstrap.enabled", "true");class, args);
}
}
参考:
SpringBoot 与 SpringCloud 版本说明:https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E