<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      技術面:SpringBoot(啟動流程、如何優雅停機)

      SpringBoot的啟動流程

      下面的代碼是SpingBoot啟動類里最基礎的代碼,SpringBoot的啟動的入口就在這里,本文是在SpringBoot3的基礎上進行的梳理。

      @SpringBootApplication
      public class Application {
      	public static void main(String[] args) {
      		SpringApplication.run(Application.class, args);
      	}
      }
      

      在網上能搜到,各種博客和文章來講解SpingBoot啟動流程的,無一不是長篇大論的,把各個步驟,各個階段執行的代碼都貼出來。
      確實,內容詳盡固然有助于理解,但面試時只需記住主干流程即可,
      誰在工作過程中,也不會無故的研究這個啟動流程,心里有個大概的了解就可以了,如果實在隔得時間太長了,寫代碼時又真的會需要了解一下這個啟動流程,那么直接在網上搜索,或者直接問AI都是可以的。

      所以本次我總結這個啟動流程的時候就是盡量的精簡步驟,然后進行總結,讓大家用自己的話,能給面試官解釋清整個流程就行了。

      另外還要說明一下,啟動流程和實現自動裝配不是一回事,啟動流程里面是包括自動裝配的。如果想了解SpringBoot是如何實現自動裝配的,可以看之前寫的文章【你來講一下springboot的啟動時的一個自動裝配過程吧】

      創建SpringBootApplication應用與刷新

      首先最核心的一段代碼SpringApplication.run(Application.class, args);這段代碼會經歷一系列的步驟,完成應用的初始化與啟動。
      這段代碼的最后是會調用到SpringApplication.classConfigurableApplicationContext方法此方法里面執行的代碼為(new SpringApplication(sources)).run(args),因此這個執行過程就分成的兩部分,第一部分是new SpringApplication(sources)另一部分是.run(args)

      public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
          return (new SpringApplication(sources)).run(args);
      }
      

      new SpringApplication(sources)

      這個構造方法的代碼如下圖所示
      在這里插入圖片描述
      弄明白了initialize()方法其實就可以了。

      • 添加應用源 this.sources.addAll(Arrays.asList(sources));這段代碼的是添加應用源的邏輯,將提供的源(通常是配置類)添加到應用的源列表中。
      • 設置 Web 環境 this.deduceWebEnvironment();判斷應用是否應該運行在 Web 環境中,這會影響后續的 Web 相關配置。
      • 加載初始化器this.getSpringFactoriesInstances(ApplicationContextInitializer.class)從 spring.factories 文件中加載所有列出的 ApplicationContextInitializer實現,并將它們設置到 SpringApplication 實例中,以便在應用上下文的初始化階段執行它們。
      • 設置監聽器this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class))加載和設置 ApplicationListener實例,以便應用能夠響應不同的事件。
      • 確定主應用類this.deduceMainApplicationClass(),這個主應用程序類通常是包含 public static void main(String[]args)方法的類,是啟動整個 Spring Boot 應用的入口點。

      SpringApplication::run(args)

      此方法就是用于啟動SpringBoot應用,也是核心流程所在。
      在這里插入圖片描述

      1、啟動計時器

      stopWatch.start();啟動計時器,用于記錄啟動耗時。

      2、獲取和啟動監聽器
      SpringApplicationRunListeners listeners = this.getRunListeners(args);
      listeners.starting();
      

      這一步從spring.factories中解析初始所有的SpringApplicationRunListener 實例,并通知
      他們應用的啟動過程已經開始。

      3、裝配環境參數
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
      

      這一步主要是用來做參數綁定的,prepareEnvironment 方法會加載應用的外部配置。這包括application.propertiesapplication.yml 文件中的屬性,環境變量,系統屬性等。所以,我們自定義的那些參數就是在這一步被綁定的。

      private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
          ConfigurableEnvironment environment = this.getOrCreateEnvironment();
          this.configureEnvironment(environment, applicationArguments.getSourceArgs());
          listeners.environmentPrepared(environment);
          if (!this.webEnvironment) {
              environment = (new EnvironmentConverter(this.getClassLoader())).convertToStandardEnvironmentIfNecessary(environment);
          }
          return environment;
      }
      
      4、創建應用上下文
      context = this.createApplicationContext();
      

      到這一步就真的開始啟動了,第一步就是先要創建一個Spring的上下文出來,只有有了這個上下文才能進行Bean的加載、配置等工作。

      5、準備上下文

      這一步很關鍵了,有很多核心操作在這里。

      this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
      

      preareContent()方法代碼如下,每一步都加上了注釋說明。

      private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
      	  // 設置環境變量
          context.setEnvironment(environment);
          // 對應用上下文進行處理,一些自定義處理邏輯也在這里
          this.postProcessApplicationContext(context);
          // 應用所有的ApplicationContentInitializer
          this.applyInitializers(context);
          // 通知監聽器上下文準備完畢工作已完成。
          listeners.contextPrepared(context);
          // 記錄啟動信息和使用的配置文件信息
          if (this.logStartupInfo) {
              this.logStartupInfo(context.getParent() == null);
              this.logStartupProfileInfo(context);
          }
      
      // 向應用上下文中添加指定的單例Bean    
      context.getBeanFactory().registerSingleton("springApplicationArguments", applicationArguments);
          if (printedBanner != null) {
              context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
          }
      		// 加載配置應用源
          Set<Object> sources = this.getSources();
          Assert.notEmpty(sources, "Sources must not be empty");
          this.load(context, sources.toArray(new Object[sources.size()]));
          // 通知監聽器上下文加載已完成
          listeners.contextLoaded(context);
      }
      
      6、刷新上下文

      this.refreshContext(context);這一步,是Spring啟動的核心步驟了,這一步驟包括了實例化所有的 Bean、設置它們之間的依賴關系以及執行其他的初始化任務。

      public void refresh() throws BeansException, IllegalStateException {
              synchronized(this.startupShutdownMonitor) {
               // 為此刷新操作準備
               this.prepareRefresh();
               // 通知子類刷新內部bean工廠
               ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
               // 為刷新做好bean工廠的準備
               this.prepareBeanFactory(beanFactory);
      
               try {
               // 允許在上下文子類中對bean工廠進行處理
                   this.postProcessBeanFactory(beanFactory);
                   // 調用在上下文中注冊為Bean的工廠處理器
                   this.invokeBeanFactoryPostProcessors(beanFactory);
                   // 注冊攔截bean創建的bean處理器
                   this.registerBeanPostProcessors(beanFactory);
                   // 初始化此上下文的消息源
                   this.initMessageSource();
                   // 初始化上下文的的時間多播器
                   this.initApplicationEventMulticaster();
                   // 在特定上下文子類中初始化其他特殊Bean(tomcat等內嵌服務器也是在這一步啟動)
                   this.onRefresh();
                   // 檢測監聽器Bean并,注冊到容器
                   this.registerListeners();
                   // 實例化所有剩余的(非懶加載)單例
                   this.finishBeanFactoryInitialization(beanFactory);
                   // 最后一步,發布相應的事件
                   this.finishRefresh();
               } catch (BeansException var9) {
                   if (this.logger.isWarnEnabled()) {
                       this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                   }
      						// 銷毀已經創建的單利
                   this.destroyBeans();
                   // 重置”激活“標志
                   this.cancelRefresh(var9);
                   // 拋出異常
                   throw var9;
               } finally {
               // 在spring的核心中重置常見的內存緩存,因為我們可能不再需要單例Bean的元數據
                   this.resetCommonCaches();
               }
      
           }
       }
      
      7、執行 CommandLineRunner 和 ApplicationRunner

      this.afterRefresh(context, applicationArguments);執行啟動參數命令或在應用完全啟動后執行一些初始化邏輯,常用于數據初始化。

      8、啟動完成,返回 ApplicationContext

      最終,run() 方法返回一個 ConfigurableApplicationContext,即 Spring 容器上下文,應用正式運行。

      總結一下,可以用下面的話來回答面試:

      SpringBoot啟動流程從SpringApplication.run()開始,通過new SpringApplication()初始化應用源、判斷Web環境、加載spring.factories中的初始化器和監聽器,并確定主類;隨后在run()中準備環境(加載配置)、創建ApplicationContext(如Web應用為ServletWebServerApplicationContext),通過refresh()完成Bean定義加載(含@EnableAutoConfiguration自動配置)、實例化單例Bean并啟動內嵌服務器(如Tomcat),最后執行CommandLineRunner等初始化邏輯,最終返回ApplicationContext使應用運行。
      在這里插入圖片描述

      SpringBoot如何優雅的停機

      優雅停機(Graceful Shutdown)是指在應用停止時,系統能夠有序地完成當前正在處理的任務,拒絕新請求,釋放資源,從而避免請求中斷和數據丟失,確保用戶體驗和數據一致性。

      SpringBoot 2.3版本開始,框架原生支持優雅停機機制,這是最簡單且官方推薦的實現方式。

      使用方式,只需要在配置文件里面進行配置即可。

      # 啟用優雅停機模式
      server.shutdown=graceful
      
      # 設置等待請求完成的超時時間(默認30秒)
      spring.lifecycle.timeout-per-shutdown-phase=30s
      

      工作原理

      當應用接收到停止信號(如SIGTERM)時,內嵌Web服務器(Tomcat/Jetty/Undertow)會執行以下步驟:

      • 停止接收新請求:內嵌服務器停止接收新的HTTP請求。
      • 等待處理中請求:繼續處理已接收的請求,直到超時。
      • 關閉應用上下文:按順序銷毀所有Bean(執行@PreDestroy方法),停止Web服務器。
      • 釋放資源:釋放數據庫連接、線程池等資源。

      不同 web服務器,優雅停機行為會有一定的差異。

      服務器 優雅停機行為
      Tomcat 停止接收新連接,等待處理中的請求完成,超時后強制關閉
      Jetty 停止接收新請求,等待活躍請求完成
      Undertow 關閉監聽端口,等待活躍請求完成

      使用SpringBoot Actuator實現優雅停機

      使用SpringBoot Actuator實現優雅停機,也就是需要HTTP端點觸發優雅停機,需要額外配置:
      pom.xml增加依賴

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-actuator</artifactId>
      </dependency>
      

      配置文件

      # 啟用shutdown端點
      management.endpoint.shutdown.enabled=true
      # 暴露shutdown端點
      management.endpoints.web.exposure.include=shutdown
      

      觸發優雅停機

      curl -X POST http://localhost:8080/actuator/shutdown
      

      Kubernetes環境下的最佳實踐

      在Kubernetes環境中,優雅停機需要與K8s生命周期配合。
      首先,配置文件里面需要進行配置

      # 啟用優雅停機模式
      server.shutdown=graceful
      # 設置等待請求完成的超時時間(默認30秒)
      spring.lifecycle.timeout-per-shutdown-phase=30s
      

      Kubernetes Deployment配置

      terminationGracePeriodSeconds: 30
      livenessProbe:
        httpGet:
          path: /health
          port: 8080
        initialDelaySeconds: 10
        periodSeconds: 5
      readinessProbe:
        httpGet:
          path: /health
          port: 8080
        initialDelaySeconds: 10
        periodSeconds: 5
      

      優雅停機具體的實現原理,主要有這幾步

      • 信號接收階段:通過Runtime.getRuntime().addShutdownHook()注冊JVM關閉鉤子,或通過Actuator端點接收停機請求
      • 應用上下文關閉階段:發布ContextClosedEvent事件,按順序銷毀所有Bean,停止內嵌Web服務器
      • 連接器優雅停止階段:不同服務器實現方式不同,但都確保等待處理中請求完成
      posted @ 2025-10-28 10:12  紀莫  閱讀(67)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 爱如潮水日本免费观看视频| 国产香蕉九九久久精品免费| 最新偷拍一区二区三区| www亚洲精品| 精品国产免费第一区二区三区| 国产免费午夜福利蜜芽无码| 国内熟女中文字幕第一页| 日本丰满少妇高潮呻吟| 欧美最猛性xxxxx大叫| 亚洲人成电影在线天堂色| 龙南县| 日本偷拍自影像视频久久| 中文字幕日韩人妻一区| 99精品国产丝袜在线拍国语| 国产欧美综合在线观看第十页| 亚洲熟女国产熟女二区三区| 国产精品久久一区二区三区| 久久88香港三级台湾三级播放| 天堂亚洲免费视频| 国产成人精品久久一区二| 波多野结衣的av一区二区三区| 左权县| 成人午夜大片免费看爽爽爽| 少妇人妻偷人免费观看| 亚洲精品www久久久久久| 极品人妻少妇一区二区三区| 欧美成人精品一级在线观看| 国产人妻高清国产拍精品| 蓬莱市| 国产仑乱无码内谢| 亚洲 成人 无码 在线观看| 亚洲乱码中文字幕小综合| 在线中文字幕国产精品| 55夜色66夜色国产精品视频| 一本久道久久综合狠狠躁av| 国产精品自在欧美一区| 久久一日本道色综合久久| 国产精品1区2区3区在线观看| 亚洲黄色一级片在线观看| 国产亚洲一二三区精品| 日本成熟少妇激情视频免费看|