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

SpringBoot配置文件啟動(dòng)加載順序的方法步驟

 更新時(shí)間:2024年11月10日 08:30:47   作者:A_aspectJ項(xiàng)目開(kāi)發(fā)  
SpringBoot的啟動(dòng)加載順序涉及多個(gè)步驟和組件,通過(guò)分層和優(yōu)先級(jí)機(jī)制加載配置文件,確保在啟動(dòng)時(shí)正確配置應(yīng)用程序,本文就來(lái)介紹一下SpringBoot配置文件啟動(dòng)加載順序的方法步驟,感興趣的可以了解一下

前言

Spring Boot的啟動(dòng)加載順序是一個(gè)涉及多個(gè)步驟和組件的過(guò)程。Spring Boot通過(guò)一系列默認(rèn)設(shè)置簡(jiǎn)化了應(yīng)用程序的配置,使得開(kāi)發(fā)者能夠快速地搭建和部署應(yīng)用。為了實(shí)現(xiàn)這一目標(biāo),Spring Boot采用了一種分層和優(yōu)先級(jí)機(jī)制來(lái)加載配置文件。

一、Spring Boot 配置文件的加載順序

1)bootstrap.properties 或 bootstrap.yml (如果存在)

application.properties 或 application.yml

2)命令行參數(shù)

3)操作系統(tǒng)環(huán)境變量

4)從 RandomValuePropertySource 生成的 random.* 屬性

5)由 @TestPropertySource 注解聲明的屬性

6)由 @SpringBootTest 注解并且 #properties 注解屬性的測(cè)試屬性

7)由 SpringBootApplication 注解的 exclude 屬性排除的自動(dòng)配置的類(lèi)

8)由應(yīng)用程序的 RandomValuePropertySource 生成的 random.* 屬性

9)在 application.properties 或 application.yml 中使用 SpringApplication 的 setDefaultProperties 方法設(shè)置的屬性

這個(gè)加載順序是有意為此的,因?yàn)橛行傩孕枰诤罄m(xù)加載的時(shí)候覆蓋前面的同名屬性。

這里是一個(gè)簡(jiǎn)單的例子,演示如何使用 bootstrap.properties 來(lái)配置一些在 Spring Boot 啟動(dòng)時(shí)需要的屬性:

 bootstrap.properties

# bootstrap.properties
spring.application.name=myapp
spring.profiles.active=prod

或者 application.yml: 

# application.yml
server:
  port: 8080

命令行參數(shù)可以用于覆蓋特定的屬性,例如: 

java -jar myapp.jar --server.port=9090

 二、在Spring Boot中,配置文件的加載順序遵循以下步驟

  • 自動(dòng)加載:Spring Boot在啟動(dòng)時(shí)會(huì)掃描特定位置的配置文件。這些位置包括jar包內(nèi)的classpath路徑、當(dāng)前項(xiàng)目的根目錄以及桌面上的文件路徑。Spring Boot會(huì)優(yōu)先加載高優(yōu)先級(jí)的配置文件,并在低優(yōu)先級(jí)配置文件被加載時(shí)覆蓋掉沖突的屬性。
  • 自定義配置文件:開(kāi)發(fā)者可以通過(guò)spring.config.name屬性指定自定義配置文件名。Spring Boot會(huì)按照以下順序查找這些配置文件:application.和application-default.,并根據(jù)擴(kuò)展名的優(yōu)先級(jí)進(jìn)行加載。擴(kuò)展名包括:.properties、.xml、.yml、.yaml。
  • 命令行參數(shù):開(kāi)發(fā)者可以在命令行中指定一些參數(shù)來(lái)覆蓋默認(rèn)的配置值。這些參數(shù)將優(yōu)先于任何其他配置文件中的值生效。
  • 環(huán)境變量:環(huán)境變量也可以用來(lái)覆蓋配置文件中的屬性值。這些變量在應(yīng)用程序啟動(dòng)時(shí)自動(dòng)加載,無(wú)需額外操作。
  • 屬性占位符:在配置文件中,可以使用${...}語(yǔ)法來(lái)引用其他屬性的值。這種方式可以創(chuàng)建依賴(lài)關(guān)系,使得某些屬性在其他屬性被解析后才能確定其值。
  • 自動(dòng)配置類(lèi):Spring Boot提供了一系列的自動(dòng)配置類(lèi),可以根據(jù)項(xiàng)目需求自動(dòng)配置一些組件。開(kāi)發(fā)者可以通過(guò)禁用特定的自動(dòng)配置類(lèi)或自定義自動(dòng)配置類(lèi)來(lái)覆蓋默認(rèn)設(shè)置。
  • 條件注解:Spring Boot允許使用條件注解來(lái)控制特定組件的創(chuàng)建。例如,只有當(dāng)某個(gè)屬性存在或滿(mǎn)足特定條件時(shí),某個(gè)bean才會(huì)被創(chuàng)建。
  • 外部化配置:Spring Boot支持將部分配置移動(dòng)到外部屬性文件中,以提高可維護(hù)性和復(fù)用性。這些外部屬性文件可以包含在jar包內(nèi)部、當(dāng)前項(xiàng)目根目錄或其他指定位置。

總結(jié)來(lái)說(shuō),Spring Boot的配置加載順序遵循以下原則:優(yōu)先從高優(yōu)先級(jí)的源加載配置,并在低優(yōu)先級(jí)源加載時(shí)覆蓋沖突的屬性;開(kāi)發(fā)者可以通過(guò)自定義配置文件、命令行參數(shù)和環(huán)境變量來(lái)覆蓋默認(rèn)值;自動(dòng)配置類(lèi)和條件注解允許更靈活地控制組件的創(chuàng)建;而外部化配置則提高了應(yīng)用程序的維護(hù)性和復(fù)用性。了解這個(gè)加載順序有助于更好地管理和優(yōu)化Spring Boot應(yīng)用程序的配置。

關(guān)鍵步驟劃分的Spring Boot啟動(dòng)加載順序的概述: 

三、啟動(dòng)準(zhǔn)備階段

  • 裝載核心啟動(dòng)器類(lèi):org.springframework.boot.SpringApplication。
  • 通過(guò)構(gòu)造函數(shù)創(chuàng)建SpringApplication實(shí)例時(shí),進(jìn)行一系列的初始化工作。

四、配置加載階段

  • Spring Boot項(xiàng)目會(huì)按照特定的順序加載配置文件,這些配置文件可以是application.properties或application.yml格式。

配置文件的加載順序(優(yōu)先級(jí)由高到低):

  • file:./config/(項(xiàng)目根路徑下的config文件夾)
  • file:./(項(xiàng)目根路徑)
  • classpath:/config/(類(lèi)路徑下的config文件夾)
  • classpath:/(類(lèi)路徑)

外部配置文件的加載方式:

  • 命令行參數(shù):可以直接在啟動(dòng)命令后添加啟動(dòng)參數(shù)。
  • spring.config.location:用于指定配置文件的新位置。

如果多個(gè)文件有相同的key,高優(yōu)先級(jí)的值會(huì)覆蓋低優(yōu)先級(jí)的值。

五、上下文準(zhǔn)備階段

  • 準(zhǔn)備并刷新應(yīng)用上下文(Context)。
  • 加載所有的初始化器(如從META-INF/spring.factories配置文件中加載的)。
  • 加載所有的監(jiān)聽(tīng)器(也是從META-INF/spring.factories配置文件中加載的)。

六、啟動(dòng)執(zhí)行階段

  • 觸發(fā)所有CommandLineRunner執(zhí)行。
  • 執(zhí)行自定義的初始化邏輯(如果有的話(huà))。

七、完成階段

  • 啟動(dòng)完成,等待退出。

注意

  • 帶profile的配置文件(如application-dev.yml)通常具有比不帶profile的配置文件(如application.yml)更高的優(yōu)先級(jí)。

代碼演示,項(xiàng)目啟動(dòng)成功后執(zhí)行一段初始化邏輯:

八、啟動(dòng)main方法中添加初始化邏輯

在Spring Boot的main入口啟動(dòng)方法中,執(zhí)行SpringApplication.run(LimitApplication.class, args)是可以返回ApplicationContext對(duì)象的,我們可以從ApplicationContext中獲取指定的bean對(duì)象,執(zhí)行初始化邏輯。

@SpringBootApplication(scanBasePackages = {"com.xinda.springbootday01.service"})
public class OrderApplication {

    public static void main(String[] args){
        //啟動(dòng)的run方法
        ApplicationContext context =  SpringApplication.run(OrderApplication.class, args);

        //啟動(dòng)執(zhí)行操作:從context中獲取指定的bean,調(diào)度初始化邏輯
        OrderService orderService = (OrderService)context.getBean("OrderServiceImpl");
        orderService.preLoadCache();
    }

}

初始化邏輯: 

@Service
public class OrderServiceImpl implements OrderService {
    @Override
    public void preLoadCache(){
        System.out.println("應(yīng)用啟動(dòng)完成:開(kāi)始執(zhí)行緩存預(yù)加載操作");
    }
}

九、實(shí)現(xiàn)ApplicationRunner或CommandLineRunner接口

在Spring Boot框架中,給我們提供了ApplicationRunner和CommandLineRunner接口來(lái)幫助我們解決項(xiàng)目啟動(dòng)后的初始化資源操作。
如果有多個(gè)ApplicationRunner、CommandLineRunner的實(shí)現(xiàn)類(lèi),可以通過(guò)@Order注解進(jìn)行排序,參數(shù)值小的先執(zhí)行。

實(shí)現(xiàn)CommandLineRunner接口:

@Order(1)
@Component
@Slf4j
public class CommandLineRunnerImpl implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("應(yīng)用啟動(dòng)完成,開(kāi)始執(zhí)行CommandLineRunner方法完成資源初始化");
    }
}

實(shí)現(xiàn)ApplicationRunner接口:

@Order(2)
@Component
@Slf4j
public class ApplicationRunnerImpl implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("應(yīng)用啟動(dòng)完成,開(kāi)始執(zhí)行ApplicationRunner方法完成資源初始化");
    }
}

源碼分析:在SpringApplication的run方法中,有這么一段核心代碼

public ConfigurableApplicationContext run(String... args) {
        long startTime = System.nanoTime();
        DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
        ConfigurableApplicationContext context = null;
        this.configureHeadlessProperty();
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting(bootstrapContext, this.mainApplicationClass);

        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();
            context.setApplicationStartup(this.applicationStartup);
            this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
            Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
            }

            listeners.started(context, timeTakenToStartup);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var12) {
            this.handleRunFailure(context, var12, listeners);
            throw new IllegalStateException(var12);
        }

        try {
            Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
            listeners.ready(context, timeTakenToReady);
            return context;
        } catch (Throwable var11) {
            this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var11);
        }
    }

十、ApplicationListener監(jiān)聽(tīng)啟動(dòng)完成事件

通過(guò)源碼,我們發(fā)現(xiàn)在Spring Boot啟動(dòng)過(guò)程中,框架內(nèi)部定義了很多事件SpringApplicationEvent,用來(lái)通知SpringApplicationRunListeners監(jiān)聽(tīng)器,以針對(duì)各種事件執(zhí)行對(duì)應(yīng)的邏輯處理。而Spring Boot啟動(dòng)完成的事件對(duì)應(yīng)的是ApplicationStartedEvent,我們可以通過(guò)自定義監(jiān)聽(tīng)器來(lái)監(jiān)聽(tīng)ApplicationStartedEvent事件,然后執(zhí)行初始化資源的相關(guān)操作。

@Component
class StartedEventListener implements ApplicationListener<ApplicationStartedEvent> {
    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        System.out.println("應(yīng)用啟動(dòng)完成,通知監(jiān)聽(tīng)器執(zhí)行緩存預(yù)加載操作");
    }
}

總結(jié)

Spring Boot支持兩種類(lèi)型的配置文件:application.properties和application.yml。當(dāng)同一個(gè)目錄下同時(shí)存在這兩種類(lèi)型的配置文件時(shí),application.properties會(huì)優(yōu)先加載,但兩種文件會(huì)進(jìn)行互補(bǔ)配置。即,如果同一配置項(xiàng)在兩個(gè)配置文件中都進(jìn)行了設(shè)置,那么application.properties中的配置會(huì)覆蓋application.yml中的配置。

除了上述默認(rèn)的配置文件加載位置外,Spring Boot還支持多種外部配置方式,它們的優(yōu)先級(jí)從高到低如下:

1)命令行參數(shù):通過(guò)java -jar命令啟動(dòng)應(yīng)用時(shí),可以在命令后附加–配置項(xiàng)=值的形式來(lái)指定配置。

2)來(lái)自java:comp/env的JNDI屬性。

3)Java系統(tǒng)屬性(System.getProperties())。

4)操作系統(tǒng)環(huán)境變量。

5)RandomValuePropertySource配置的random.*屬性值:用于生成隨機(jī)值。

6)jar包外部的帶profile的配置文件(如application-{profile}.properties或application-{profile}.yml)。

7)jar包內(nèi)部的帶profile的配置文件。

8)jar包外部的不帶profile的配置文件(如application.properties或application.yml)。

9)jar包內(nèi)部的不帶profile的配置文件。

(由jar包外向jar包內(nèi)進(jìn)行尋找,優(yōu)先加載帶profile的,再加載不帶profile的。)

10)@Configuration注解類(lèi)上的@PropertySource。

11)通過(guò)SpringApplication.setDefaultProperties指定的默認(rèn)屬性。

另外,可以通過(guò)spring.config.location屬性來(lái)改變默認(rèn)的配置文件位置。

在項(xiàng)目打包后,可以使用命令行參數(shù)的形式來(lái)指定配置文件的新位置,指定的配置文件和默認(rèn)加載的配置文件會(huì)共同起作用,形成互補(bǔ)配置。

當(dāng)使用多環(huán)境配置時(shí)(如開(kāi)發(fā)、測(cè)試、生產(chǎn)環(huán)境),可以通過(guò)激活不同的profiles來(lái)加載對(duì)應(yīng)的配置文件。

到此這篇關(guān)于SpringBoot配置文件啟動(dòng)加載順序的方法步驟的文章就介紹到這了,更多相關(guān)SpringBoot配置文件啟動(dòng)加載順序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論