亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

新版SpringBoot無法主動讀取bootstrap.yml的原因和解決方法

 更新時間:2025年01月10日 09:29:15   作者:小白的一葉扁舟  
在使用新版 Springboot 搭建微服務(wù)時 發(fā)現(xiàn)配置數(shù)據(jù)源失敗,依賴、配置、注解等所示所有均為正確,所以本文給大家介紹了新版SpringBoot無法主動讀取bootstrap.yml的原因和解決方案,需要的朋友可以參考下

技術(shù)棧:

Springboot 2024.0.0 + MyBatisPlus3 + MySql8 + Hikari連接池

前言:

在使用新版 Springboot 搭建微服務(wù)時 發(fā)現(xiàn)配置數(shù)據(jù)源失?。‵ailed to configure a DataSource: ‘url‘ attribute is not specified and no emb)如下圖依賴 配置 注解等所示 所有均為正確

注意:

因追蹤代碼過長 所以放在最后方 有興趣的可以看一下

相關(guān)依賴如下:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.4.1</version>
    <relativePath/>
</parent>

<dependencies>
    <!-- MySQL Connector -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.31</version>
    </dependency>
    <!-- Mybatis-Plus -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.9</version>
    </dependency>
</dependencies>

相關(guān)配置如下:

# DataSource 配置
spring:
  application:
    name: ai-grading-base # 服務(wù)名 將在 Eureka 中注冊
  datasource:
    url: jdbc:mysql://localhost:3306/xxx-xxx?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: xxx
    password: yyy
    hikari:
      maximum-pool-size: 10  # 設(shè)置最大連接池大小
      minimum-idle: 5        # 最小空閑連接數(shù)
      idle-timeout: 30000    # 空閑連接的最大存活時間 單位:毫秒
      max-lifetime: 600000   # 連接最大生命周期 單位:毫秒
      connection-timeout: 30000  # 連接超時時間 單位:毫秒
      validation-timeout: 5000    # 校驗連接的超時時間 單位:毫秒
      leak-detection-threshold: 15000  # 連接泄漏檢測閾值 單位:毫秒
      pool-name: HikariCP      # 連接池的名稱
      auto-commit: true        # 是否啟用自動提交

# MyBatis 配置
mybatis-plus:
  mapper-locations: classpath:mapper/*Mapper.xml
  type-aliases-package: xxx.xxx.xxx.pojo  
  configuration:
    map-underscore-to-camel-case: true
    #開啟日志打印
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

啟動類注解:

@MapperScan("xxx.xx.xxx.mapper")
@SpringBootApplication
public class AiGradingBaseApplication {
    public static void main(String[] args) {
        SpringApplication.run(AiGradingBaseApplication.class, args);
    }
}

配置數(shù)據(jù)源失?。‵ailed to configure a DataSource: ‘url‘ attribute is not specified and no emb)

開發(fā)場景:

采用 Mysql 8 配置 bootstrap.yml 失敗

報錯原因:

在 Spring Boot 2.4 之前 配置文件的加載順序是按照以下順序進行的:

  1. application.properties
  2. application.yml
  3. bootstrap.properties
  4. bootstrap.yml

其中 bootstrap.yml 的加載優(yōu)先級大于 application.yml 因此如果同一個配置項在兩個文件中都有定義 bootstrap.yml 中的值會覆蓋 application.yml 中的值

配置文件加載優(yōu)先級

  • bootstrap.yml: 用于在應(yīng)用程序啟動時加載應(yīng)用上下文之前的配置 通常用于配置服務(wù)發(fā)現(xiàn) 配置中心等
  • application.yml: 用于在應(yīng)用程序上下文加載之后加載配置 通常用于業(yè)務(wù)相關(guān)的配置

關(guān)鍵點:

  • bootstrap.yml 在 Spring Boot 2.4 之前的版本中有更高的優(yōu)先級 因此如果配置在 bootstrap.yml 和 application.yml 中重復定義 bootstrap.yml 中的配置會生效
  • 從 Spring Boot 2.4 開始 bootstrap.yml 已經(jīng)被移除 并且將其功能移交給 application.yml 和 application.properties Spring Cloud 配置被集成到 application.yml 中
  • 如果使用的是 Spring Boot 2.4 之后的版本 應(yīng)該最好禁用 bootstrap.yml 改用 application.yml 來進行配置

主要解決方案一:將 bootstrap.yml 配置移動至 application.yml 既可

主要解決方案二:認真檢查MySql(datascoure)配置文件是否有誤 特別是Tab縮進等 可參考上方貼出的配置

主要解決方案三:使用 spring.cloud.bootstrap.enabled 屬性啟用引導配置

bootstrap.yml 文件的引導配置仍然可以通過設(shè)置 spring.cloud.bootstrap.enabled 屬性來啟用 如果該屬性設(shè)置為 true Spring Cloud 將嘗試加載 bootstrap.yml 文件 并將其中的配置應(yīng)用于應(yīng)用程序的環(huán)境中

關(guān)鍵步驟:

  • 確保 spring.cloud.bootstrap.enabled=true 配置被激活 可以通過系統(tǒng)屬性 環(huán)境變量或配置文件中設(shè)置
  • bootstrap.yml 會被自動加載并包含在 Spring 環(huán)境中

例如 可以在 application.properties 或 application.yml 中配置:

spring.cloud.bootstrap.enabled=true

或者通過環(huán)境變量或系統(tǒng)屬性傳遞:

-Dspring.cloud.bootstrap.enabled=true

代碼層面:

在新版 Spring Cloud 中 PropertyUtils.bootstrapEnabled() 方法會檢查 spring.cloud.bootstrap.enabled 屬性的值以及 Marker 類的存在 從而決定是否啟用 bootstrap 配置

public static boolean bootstrapEnabled(Environment environment) {
    return (Boolean) environment.getProperty("spring.cloud.bootstrap.enabled", Boolean.class, false) || MARKER_CLASS_EXISTS;
}

主要解決方案四:讀取 bootstrap.yml 配置文件

在新版 Spring Cloud 中 bootstrap.yml 文件可以直接通過 Spring 的配置機制加載 通常無需手動指定文件路徑 Spring Cloud 會根據(jù) spring.cloud.bootstrap.enabled 屬性的設(shè)置決定是否加載 bootstrap.yml 或 bootstrap.properties 文件

典型的 bootstrap.yml 配置文件:

spring:
  cloud:
    config:
      uri: http://localhost:8888
    bootstrap:
      enabled: true

該配置告訴 Spring Cloud Config Client 從指定的 Config Server 獲取配置 并在應(yīng)用程序啟動時加載

主要解決方案五: 使用 ConfigurableEnvironment 和 ApplicationContext 讀取引導配置

在 Spring Cloud 中 可以通過 ConfigurableEnvironment 或 ApplicationContext 來訪問和讀取 bootstrap.yml 配置文件中的屬性

ConfigurableEnvironment environment = event.getEnvironment();
String configUri = environment.getProperty("spring.cloud.config.uri", String.class, "http://localhost:8888");

通過這種方式 可以讀取 bootstrap.yml 文件中配置的其他屬性(如 spring.cloud.config.uri) 并將其用于應(yīng)用程序的初始化過程

主要解決方案六: 手動加載 bootstrap.yml 文件(如果需要)

在一些特定的應(yīng)用場景下 可能需要手動加載 bootstrap.yml 文件 Spring 提供了多種方式加載外部配置文件 包括使用 @PropertySource 注解或者 Environment 對象 此方法一般用于需要手動控制文件加載順序或路徑的情況

@Configuration
@PropertySource("classpath:/bootstrap.yml")
public class BootstrapConfig {
    @Value("${spring.cloud.config.uri}")
    private String configUri;
}

主要解決方案七: 通過 @EnableConfigurationProperties 綁定配置

如果希望將 bootstrap.yml 配置文件中的屬性綁定到一個配置類中 可以使用 @EnableConfigurationProperties 注解來啟用屬性綁定 這種方式在新版中也非常常見

@Configuration
@EnableConfigurationProperties(ConfigProperties.class)
public class ConfigBootstrap {
    // 自動注入配置類
    @Autowired
    private ConfigProperties configProperties;
}

其中 ConfigProperties 類可以定義從 bootstrap.yml 文件中讀取的配置屬性:

@ConfigurationProperties(prefix = "spring.cloud.config")
public class ConfigProperties {
    private String uri;

    // Getter and Setter
}

主要解決方案八: 通過 ApplicationContextInitializer 初始化 bootstrap.yml 配置

Spring Cloud 使用了 ApplicationContextInitializer 來初始化 Spring 應(yīng)用上下文 在 BootstrapApplicationListener 中 ApplicationContextInitializer 被用來處理 bootstrap.yml 配置的加載和處理

如果你需要定制加載邏輯 可以通過實現(xiàn)自己的 ApplicationContextInitializer 來進一步控制 bootstrap.yml 的加載順序和方式:

public class CustomBootstrapApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        // 自定義初始化邏輯 處理 bootstrap 配置
    }
}

并在 SpringApplication 啟動時注冊這個初始化器:

SpringApplication app = new SpringApplication(MyApplication.class);
app.addInitializers(new CustomBootstrapApplicationContextInitializer());
app.run(args);

主要解決方案九: 使用 SpringApplication 配置程序的監(jiān)聽器

Spring Cloud 使用了 BootstrapApplicationListener 來處理 bootstrap.yml 文件的加載和應(yīng)用配置 它在 ApplicationEnvironmentPreparedEvent 事件中觸發(fā) 并將配置應(yīng)用到 Spring 環(huán)境

public class BootstrapApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
        ConfigurableEnvironment environment = event.getEnvironment();
        if (PropertyUtils.bootstrapEnabled(environment)) {
            // 初始化 bootstrap 上下文 加載 bootstrap.yml 配置
        }
    }
}

其余解決方案一:添加節(jié)點 保證文件被正常被掃描并成功加載(以 SpringBoot 3.4.1 舉例 官方已在依賴中聲明 resources 中內(nèi)容 所以不用單獨聲明)

<build>
    <finalName>xx-xx-xx</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
            <include>/*.yml</include>
            <include>/*.properties</include>
            <include>/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
            <include>/*.yml</include>
            <include>/*.properties</include>
            <include>/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

其余方式二(除特殊場景外 其余皆不推薦):在啟用類上添加注解聲明不需要加載數(shù)據(jù)源(DataSourceAutoConfiguration)

@MapperScan("xxx.xxx.xxx.mapper")
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
public class AiGradingBaseApplication {
    public static void main(String[] args) {
        SpringApplication.run(AiGradingBaseApplication.class, args);
    }
}

其余方式三(除特殊場景外 其余皆不推薦):在配置文件中聲明不需要加載數(shù)據(jù)源(DataSourceAutoConfiguration)跟方式二同理 只是操作方式不一致

spring:
 autoconfigure:
 	exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

源碼追蹤:

前言:因 Springboot 舊版及新版中針對于 bootstrap.yml 文件加載進行重構(gòu)

官方:

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. Once bootstrap has been enabled any application with Spring Cloud Config Client on the classpath will connect to Config Server as follows: When a config client starts, it binds to the Config Server (through the spring.cloud.config.uri bootstrap configuration property) and initializes Spring Environment with remote property sources.

The net result of this behavior is that all client applications that want to consume the Config Server need a bootstrap.yml (or an environment variable) with the server address set in spring.cloud.config.uri (it defaults to "http://localhost:8888").

翻譯:

配置引導方式(Config First Bootstrap)
要使用傳統(tǒng)的引導方式連接到 Config Server 必須通過屬性或 spring-cloud-starter-bootstrap 啟動器來啟用引導 相關(guān)的屬性是 spring.cloud.bootstrap.enabled=true 該屬性必須作為系統(tǒng)屬性或環(huán)境變量進行設(shè)置 一旦啟用了引導 任何包含 Spring Cloud Config Client 的應(yīng)用程序都會按照以下方式連接到 Config Server:
當一個配置客戶端啟動時 它會綁定到 Config Server(通過 spring.cloud.config.uri 引導配置屬性)并使用遠程屬性源初始化 Spring 環(huán)境 
這種行為的最終結(jié)果是 所有希望使用 Config Server 的客戶端應(yīng)用程序都需要一個包含服務(wù)器地址配置的 bootstrap.yml 文件(或者通過環(huán)境變量設(shè)置) 該配置項為 spring.cloud.config.uri(默認為 "http://localhost:8888") 

簡述:

在 Spring Cloud 的早期版本中 bootstrap.yml 是配置 Spring Cloud Config Client 的關(guān)鍵文件 要啟用傳統(tǒng)的引導方式連接到 Config Server 必須通過 spring.cloud.bootstrap.enabled=true 屬性或通過 spring-cloud-starter-bootstrap 啟動器來啟用引導

傳統(tǒng)引導方式:

  • 配置屬性: spring.cloud.bootstrap.enabled=true 必須作為系統(tǒng)屬性或環(huán)境變量設(shè)置
  • 配置文件: 客戶端應(yīng)用程序需要一個 bootstrap.yml 文件 在其中設(shè)置 spring.cloud.config.uri 屬性(默認值是 http://localhost:8888) 指向 Config Server 的地址
  • 初始化過程: 在應(yīng)用程序啟動時 bootstrap.yml 會被加載 并通過 spring.cloud.config.uri 屬性連接到 Config Server 以獲取遠程配置

相關(guān)依賴:

<!-- 舊版 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.12.RELEASE</version>
    <relativePath/>
</parent>
<!-- 新版 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.4.1</version>
    <relativePath/>
</parent>

舊版相關(guān)源碼:

package org.springframework.cloud.bootstrap;

public class BootstrapApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {

    // 定義常量:bootstrap 配置源名稱
    public static final String BOOTSTRAP_PROPERTY_SOURCE_NAME = "bootstrap";

    // 定義常量:默認屬性名稱
    public static final String DEFAULT_PROPERTIES = "springCloudDefaultProperties";
    
    // 省略部分代碼...

    // 構(gòu)造函數(shù)
    public BootstrapApplicationListener() {
    }

    // 監(jiān)聽到 ApplicationEnvironmentPreparedEvent 事件時調(diào)用的方法
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
        // 獲取當前環(huán)境對象
        ConfigurableEnvironment environment = event.getEnvironment();
        
        // 新版 - 檢查是否啟用了 bootstrap 或使用了傳統(tǒng)的處理方式
	    // if (PropertyUtils.bootstrapEnabled(environment) || PropertyUtils.useLegacyProcessing(environment)) {
        // 舊版 - 檢查是否啟用了 bootstrap
        if ((Boolean) environment.getProperty("spring.cloud.bootstrap.enabled", Boolean.class, true)) {
        
            // 如果環(huán)境中沒有包含名為 "bootstrap" 的屬性源
            if (!environment.getPropertySources().contains("bootstrap")) {
                ConfigurableApplicationContext context = null;
                // 解析配置的 bootstrap 名稱 默認為 "bootstrap"
                String configName = environment.resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}");
                // 獲取 Spring 應(yīng)用的初始化器列表
                Iterator var5 = event.getSpringApplication().getInitializers().iterator();
                // 省略部分代碼...
            }
        }
    }
}

新版相關(guān)源碼:

package org.springframework.cloud.util;

import org.springframework.core.env.Environment;
import org.springframework.util.ClassUtils;

public abstract class PropertyUtils {
    
    // 定義常量:表示是否啟用了 bootstrap 配置
    public static final String BOOTSTRAP_ENABLED_PROPERTY = "spring.cloud.bootstrap.enabled";
    
    // 定義常量:用于標記類是否存在
    public static final boolean MARKER_CLASS_EXISTS = ClassUtils.isPresent("org.springframework.cloud.bootstrap.marker.Marker", (ClassLoader)null);

    // 判斷是否啟用了 bootstrap 配置的方法
    public static boolean bootstrapEnabled(Environment environment) {
        // 獲取 "spring.cloud.bootstrap.enabled" 配置的值 默認為 false
        return (Boolean) environment.getProperty("spring.cloud.bootstrap.enabled", Boolean.class, false) || MARKER_CLASS_EXISTS;
    }

    // 省略部分代碼...
}

相關(guān)核心代碼解釋:

在舊版本的 Spring Cloud 中 BootstrapApplicationListener 類會監(jiān)聽 ApplicationEnvironmentPreparedEvent 事件 在環(huán)境配置準備好后 檢查是否啟用了引導(spring.cloud.bootstrap.enabled)并進行初始化

  • 代碼檢查 spring.cloud.bootstrap.enabled 屬性是否為 true 如果是 則進行 bootstrap 上下文的初始化
  • 如果環(huán)境中沒有找到 "bootstrap" 配置源 則創(chuàng)建該配置源 并進行相應(yīng)的配置初始化

在新版 Spring Cloud 中 PropertyUtils 類提供了一個新的方法來判斷是否啟用了 bootstrap 配置

bootstrapEnabled 方法: 檢查是否啟用了 spring.cloud.bootstrap.enabled 配置 或者 org.springframework.cloud.bootstrap.marker.Marker 類是否存在 這個類的存在標記了某些特定功能或版本的啟用

  • spring.cloud.bootstrap.enabled 配置項通常表示是否啟用 Spring Cloud Config Client 的引導功能
  • MARKER_CLASS_EXISTS 用來檢查類 org.springframework.cloud.bootstrap.marker.Marker 是否存在 通常在新的 Spring Cloud 版本中 這個類的存在表示是否啟用某些特定的配置或功能
  • MARKER_CLASS_EXISTS 常量用于檢查 Marker 類是否存在 這是新版 Spring Cloud 引導機制的一部分 表示是否啟用 bootstrap 配置

這個方法的核心目的是根據(jù)配置和類是否存在來判斷是否啟用 bootstrap 配置源

關(guān)鍵常量

  • MARKER_CLASS_EXISTS 常量用于檢查 Marker 類是否存在 這是新版 Spring Cloud 引導機制的一部分 表示是否啟用 bootstrap 配置

傳統(tǒng)與新版的主要區(qū)別:

傳統(tǒng)引導方式(舊版):

  1. spring.cloud.bootstrap.enabled:需要顯式配置為 true 否則不會啟用 bootstrap 配置
  2. bootstrap.yml:需要手動配置 spring.cloud.config.uri 和其他屬性
  3. 代碼流程:BootstrapApplicationListener 直接在事件監(jiān)聽時檢查是否啟用 bootstrap 并根據(jù)條件進行初始化

新版引導方式:

  1. bootstrapEnabled 方法:在新版 Spring Cloud 中 PropertyUtils.bootstrapEnabled 方法提供了一種更加靈活的方式來檢查是否啟用了 bootstrap 不僅僅通過 spring.cloud.bootstrap.enabled 屬性 還通過檢查 Marker 類的存在來進行判斷
  2. Marker 類:新版加入了 org.springframework.cloud.bootstrap.marker.Marker 類 作為配置的標記類來表示是否啟用某些功能
  3. 靈活性提高:新版代碼通過 PropertyUtils 類提供的邏輯來判斷是否啟用引導功能 允許更靈活的配置和判斷

總結(jié):

  • 舊版 Spring Cloud: bootstrap.yml 是必需的配置文件 spring.cloud.bootstrap.enabled 用于控制是否啟用引導配置 啟用后 Spring Cloud Config Client 會自動連接到 Config Server
  • 新版 Spring Cloud: 引入了通過檢查 Marker 類的存在來動態(tài)啟用 bootstrap 配置的機制 使得配置加載更加靈活 并支持更多的使用場景 通過檢查 spring.cloud.bootstrap.enabled 或 Marker 類的存在 Spring Cloud 可以決定是否加載 bootstrap.yml 文件
  • PropertyUtils 類: 提供了簡化的方法來判斷是否啟用 bootstrap 配置 它通過判斷 spring.cloud.bootstrap.enabled 屬性的值以及 Marker 類的存在來決定是否啟用 bootstrap 配置 從而使新版代碼更加簡潔、靈活和可擴展
  • 加載 bootstrap.yml 文件: 在新版 Spring Cloud 中 加載 bootstrap.yml 文件依賴于 spring.cloud.bootstrap.enabled 的配置值和 Marker 類的存在 當啟用該屬性時 Spring Cloud 會自動加載 bootstrap.yml 文件 無需手動指定文件路徑 配置可以通過 ConfigurableEnvironment 或 ApplicationContext 來訪問 如果需要更復雜的控制 開發(fā)者可以通過自定義 ApplicationContextInitializer 或 ApplicationListener 來實現(xiàn)定制化的配置加載過程

這種引導方式的演變表明 Spring Cloud 在不斷優(yōu)化和簡化配置的同時 也保持了對舊版配置的兼容性

相關(guān)文章

最新評論