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

springboot加載配值文件的實(shí)現(xiàn)步驟

 更新時(shí)間:2025年03月07日 12:01:16   作者:花花進(jìn)修  
本文主要介紹了springboot加載配值文件的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

Spring Boot 加載配置文件的機(jī)制是其核心功能之一,它通過一系列源碼實(shí)現(xiàn)從不同來源加載配置,并支持靈活的配置管理。以下是 Spring Boot 加載配置文件的源碼解析及其實(shí)現(xiàn)原理的詳細(xì)說明。(下述兩段是加載配置文件的源碼片段) 

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        this.sources = new LinkedHashSet();
        this.bannerMode = Mode.CONSOLE;
        this.logStartupInfo = true;
        this.addCommandLineProperties = true;
        this.addConversionService = true;
        this.headless = true;

        this.registerShutdownHook = true;
        this.additionalProfiles = Collections.emptySet();
        this.isCustomEnvironment = false;
        this.lazyInitialization = false;
        this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
        this.applicationStartup = ApplicationStartup.DEFAULT;

        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
        //1.推測web應(yīng)用類型(NONE   REACTIVE   SERVLET)
        this.webApplicationType = WebApplicationType.deduceFromClasspath();

         //2.從spring.factories中獲取BootstrapRegistryInitializer對(duì)象
        this.bootstrapRegistryInitializers =             
       this.getBootstrapRegistryInitializersFromSpringFactories();
        
 //3.從spring.factories中獲取ApplicationContextInitializer對(duì)象
 this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
         //4.從spring.factories中獲取ApplicationListener對(duì)象
        this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
        //5.推測出Main類 (main()方法所在的類)
        this.mainApplicationClass = this.deduceMainApplicationClass();
    }
public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
        ConfigurableApplicationContext context = null;
        this.configureHeadlessProperty();
           /**從spring.factories中獲取SpringApplicationRunListeners 對(duì)象
            * 默認(rèn)會(huì)拿到一個(gè)EventPublishingRunListener ,他會(huì)啟動(dòng)過程的各個(gè)階段發(fā)布對(duì)應(yīng)的事件
            **/
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting(bootstrapContext, this.mainApplicationClass);

        try {
            //將run()的參數(shù)封裝為DefaultApplicationArguments對(duì)象
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
                //配置文件的入口
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            Banner printedBanner = this.printBanner(environment);
            //根據(jù)應(yīng)用類型創(chuàng)建Spring容器
            context = this.createApplicationContext();
            context.setApplicationStartup(this.applicationStartup);
            this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
               //刷新Spring容器, 會(huì)解析配置類  掃描  啟動(dòng)Webserver
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }

            listeners.started(context);

            //調(diào)用applicationArguments 和CommandLineRunner
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

1. Spring Boot 加載配置文件的整體流程

Spring Boot 加載配置文件的流程可以分為以下幾個(gè)步驟:

  • 初始化 Environment:在應(yīng)用啟動(dòng)時(shí),創(chuàng)建并初始化 Environment 對(duì)象。

  • 加載默認(rèn)配置文件:從 application.properties 或 application.yml 加載配置。

  • 加載 Profile 特定的配置文件:根據(jù)激活的 Profile 加載 application-{profile}.properties 或 application-{profile}.yml。

  • 加載外部化配置:從命令行參數(shù)、環(huán)境變量、JNDI 等外部來源加載配置。

  • 合并配置:將所有配置來源合并到 Environment 中,供應(yīng)用程序使用。

2. 源碼解析

以下是 Spring Boot 加載配置文件的核心源碼解析。

2.1 SpringApplication.run()

Spring Boot 應(yīng)用的啟動(dòng)入口是 SpringApplication.run() 方法。在這個(gè)方法中,會(huì)初始化 Environment 并加載配置文件。

源碼位置:org.springframework.boot.SpringApplication

public ConfigurableApplicationContext run(String... args) {
    // ...
    ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
    // ...
}

說明:

  • prepareEnvironment() 方法負(fù)責(zé)創(chuàng)建和配置 Environment 對(duì)象。

2.2 prepareEnvironment()

prepareEnvironment() 方法會(huì)調(diào)用 configureEnvironment() 來加載配置文件。

源碼位置:org.springframework.boot.SpringApplication

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
    // 創(chuàng)建 Environment 對(duì)象
    ConfigurableEnvironment environment = getOrCreateEnvironment();
    // 配置 Environment,加載配置文件
    configureEnvironment(environment, applicationArguments.getSourceArgs());
    // 觸發(fā)環(huán)境準(zhǔn)備事件
    listeners.environmentPrepared(environment);
    // 將 Environment 綁定到 SpringApplication
    bindToSpringApplication(environment);
    return environment;
}

說明:

  • getOrCreateEnvironment():根據(jù)應(yīng)用類型(Web 或非 Web)創(chuàng)建 StandardEnvironment 或 StandardServletEnvironment

  • configureEnvironment():加載配置文件和其他外部化配置。

2.3 configureEnvironment()

configureEnvironment() 方法會(huì)調(diào)用 configurePropertySources() 和 configureProfiles() 來加載配置文件和激活 Profile。

源碼位置:org.springframework.boot.SpringApplication

protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
    configurePropertySources(environment, args);
    configureProfiles(environment, args);
}

說明:

  • configurePropertySources():加載命令行參數(shù)、默認(rèn)配置文件等。

  • configureProfiles():設(shè)置激活的 Profile。

2.4 ConfigFileApplicationListener

ConfigFileApplicationListener 是 Spring Boot 加載配置文件的核心類。它監(jiān)聽 ApplicationEnvironmentPreparedEvent 事件,并加載 application.properties 或 application.yml 文件。

源碼位置:org.springframework.boot.context.config.ConfigFileApplicationListener

public void onApplicationEvent(ApplicationEvent event) {
    if (event instanceof ApplicationEnvironmentPreparedEvent) {
        onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
    }
}

說明:

onApplicationEnvironmentPreparedEvent():在環(huán)境準(zhǔn)備完成后觸發(fā),加載配置文件。

2.5 Loader.load()

Loader 是 ConfigFileApplicationListener 的內(nèi)部類,負(fù)責(zé)實(shí)際加載配置文件。

源碼位置:org.springframework.boot.context.config.ConfigFileApplicationListener.Loader

void load() {
    for (String location : getSearchLocations()) {
        for (String name : getSearchNames()) {
            load(location, name);
        }
    }
}

說明:

  • getSearchLocations():獲取配置文件的搜索路徑(如 classpath:/、file:./config/ 等)。

  • getSearchNames():獲取配置文件的名稱(如 application)。

  • load(location, name):從指定路徑加載配置文件。

2.6 PropertySourcesLoader

PropertySourcesLoader 負(fù)責(zé)將配置文件內(nèi)容加載到 PropertySource 中。

源碼位置:org.springframework.boot.env.PropertySourcesLoader

public PropertySource<?> load(Resource resource) throws IOException {
    if (resource.getFilename().endsWith(".yml")) {
        return loadYaml(resource);
    } else {
        return loadProperties(resource);
    }
}

說明:

  • loadYaml():加載 YAML 格式的配置文件。

  • loadProperties():加載 Properties 格式的配置文件。

2.7 Profile 的加載

Spring Boot 支持通過 Profile 加載不同的配置文件。Profiles 和 ProfilePropertySource 負(fù)責(zé)處理 Profile 相關(guān)的配置。

源碼位置:org.springframework.core.env.Profiles

public static Profiles of(String... profiles) {
    return new Profiles() {
        @Override
        public boolean matches(Predicate<String> predicate) {
            // ...
        }
    };
}

說明:

  • Profiles:管理 Profile 的激活狀態(tài)。

  • ProfilePropertySource:根據(jù)激活的 Profile 加載特定的配置文件。

3.Spring Boot配置文件的實(shí)現(xiàn)原理

Spring Boot 加載配置文件的實(shí)現(xiàn)原理可以總結(jié)為以下幾點(diǎn):

  • 多來源加載:支持從類路徑、外部目錄、環(huán)境變量、命令行參數(shù)等多種來源加載配置。
  • 優(yōu)先級(jí)機(jī)制:后加載的配置會(huì)覆蓋先加載的配置,命令行參數(shù)的優(yōu)先級(jí)最高。
  • Profile 支持:通過 spring.profiles.active 指定激活的 Profile,加載對(duì)應(yīng)的配置文件。
  • 外部化配置:支持從外部文件、環(huán)境變量、JNDI 等加載配置,適用于云原生和容器化部署。

4. 示例:Spring Boot 加載配置文件的流程

以下是一個(gè)完整的示例,展示 Spring Boot 如何加載配置文件。

4.1 默認(rèn)配置文件

application.properties:

server.port=8080
spring.profiles.active=dev

4.2 Profile 特定的配置文件

application-dev.properties:

server.port=8081

4.3 Java 代碼

@RestController
public class MyController {
?
    @Value("${server.port}")
    private String port;
?
    @GetMapping("/port")
    public String getPort() {
        return "Server port: " + port;
    }
}

4.4 運(yùn)行結(jié)果

  • 如果激活的 Profile 是 dev,則 server.port 的值為 8081。

  • 如果沒有激活 Profile,則 server.port 的值為 8080。

5. 總結(jié)

Spring Boot 加載配置文件的機(jī)制非常靈活,支持多來源、多格式的配置加載。通過 EnvironmentPropertySource、ConfigFileApplicationListener 等核心類和組件,Spring Boot 實(shí)現(xiàn)了配置文件的加載、合并和優(yōu)先級(jí)管理。理解這些源碼和機(jī)制,可以幫助我們更好地使用和擴(kuò)展 Spring Boot 的配置功能。

到此這篇關(guān)于springboot加載配值文件的實(shí)現(xiàn)步驟的文章就介紹到這了,更多相關(guān)springboot加載配值文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Boot中的那些條件判斷的實(shí)現(xiàn)方法

    Spring Boot中的那些條件判斷的實(shí)現(xiàn)方法

    這篇文章主要介紹了Spring Boot中的那些條件判斷的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • SpringCloud鏈路追蹤組件Sleuth配置方法解析

    SpringCloud鏈路追蹤組件Sleuth配置方法解析

    這篇文章主要介紹了SpringCloud鏈路追蹤組件Sleuth配置方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java用鄰接表存儲(chǔ)圖的示例代碼

    Java用鄰接表存儲(chǔ)圖的示例代碼

    鄰接表是圖的一種鏈?zhǔn)酱鎯?chǔ)方法,其數(shù)據(jù)結(jié)構(gòu)包括兩部分:節(jié)點(diǎn)和鄰接點(diǎn)。本文將用鄰接表實(shí)現(xiàn)存儲(chǔ)圖,感興趣的小伙伴可以了解一下
    2022-06-06
  • java 兩階段終止線程的正確做法

    java 兩階段終止線程的正確做法

    這篇文章主要給大家分享了java 兩階段終止線程的正確做法,文章列舉出錯(cuò)誤的做法與正確做法做對(duì)比,具有一定的參考價(jià)值,需要的小伙伴可以參考一下,希望對(duì)你有所幫助
    2021-12-12
  • Java結(jié)合redistemplate使用分布式鎖案例講解

    Java結(jié)合redistemplate使用分布式鎖案例講解

    在Java中使用RedisTemplate結(jié)合Redis來實(shí)現(xiàn)分布式鎖是一種常見的做法,特別適用于微服務(wù)架構(gòu)或多實(shí)例部署的應(yīng)用程序中,以確保數(shù)據(jù)的一致性和避免競態(tài)條件,下面給大家分享使用Spring Boot和RedisTemplate實(shí)現(xiàn)分布式鎖的案例,感興趣的朋友一起看看吧
    2024-08-08
  • Mybatis?Lombok使用方法與復(fù)雜查詢介紹

    Mybatis?Lombok使用方法與復(fù)雜查詢介紹

    Lombok是一種Java實(shí)用工具,可用來幫助開發(fā)人員消除Java的冗長,尤其是對(duì)于簡單的Java對(duì)象(POJO),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-10-10
  • Spring  ApplicationContextAware 接口的作用及使用方式

    Spring  ApplicationContextAware 接口的作用及使用方式

    Spring提供了許多回調(diào)接口,用于Bean生命周期中執(zhí)行特定的操作,通過實(shí)現(xiàn)ApplicationContextAware接口,Spring提供了一種便捷的方式讓 Bean獲取對(duì)Spring容器的引用,本文介紹ApplicationContextAware接口的作用、使用方式,以及在實(shí)際應(yīng)用中的常見場景,感興趣的朋友一起看看吧
    2024-01-01
  • IntelliJ?IDEA?代碼運(yùn)行時(shí)中文出現(xiàn)亂碼問題及解決方法

    IntelliJ?IDEA?代碼運(yùn)行時(shí)中文出現(xiàn)亂碼問題及解決方法

    在我們剛接觸到IDEA時(shí),想美滋滋的敲一個(gè)“hello?world”來問候這個(gè)世界,但難免會(huì)遇到這種問題亂碼,這篇文章主要介紹了解決IntelliJ?IDEA?代碼運(yùn)行時(shí)中文出現(xiàn)亂碼問題,需要的朋友可以參考下
    2023-09-09
  • Java兩整數(shù)相除向上取整的方式詳解(Math.ceil())

    Java兩整數(shù)相除向上取整的方式詳解(Math.ceil())

    在調(diào)外部接口獲取列表數(shù)據(jù)時(shí),需要判斷是否已經(jīng)取完了所有的值,因此需要用到向上取整,下面這篇文章主要給大家介紹了關(guān)于Java兩整數(shù)相除向上取整的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • Java參數(shù)按值傳遞示例演示

    Java參數(shù)按值傳遞示例演示

    在Java中,方法參數(shù)的傳遞方式實(shí)際上是按值傳遞,接下來通過本文給大家介紹了Java參數(shù)按值傳遞示例演示,需要的朋友可以參考下
    2023-09-09

最新評(píng)論