原因
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