一張圖理清ASP.NET Core啟動流程
1. 引言
對於ASP.NET Core
應用程式來說,我們要記住非常重要的一點是:其本質上是一個獨立的控制檯應用,它並不是必需在IIS內部託管且並不需要IIS來啟動執行(而這正是ASP.NET Core
跨平臺的基石)。ASP.NET Core
應用程式擁有一個內建的Self-Hosted
(自託管)的Web Server
(Web伺服器),用來處理外部請求。
不管是託管還是自託管,都離不開Host
(宿主)。在ASP.NET Core
應用中通過配置並啟動一個Host
來完成應用程式的啟動和其生命週期的管理(如下圖所示)。而Host
的主要的職責就是Web Server
的配置和Pilpeline
(請求處理管道)的構建。
這張圖描述了一個總體的啟動流程,從上圖中我們知道ASP.NET Core
應用程式的啟動主要包含三個步驟:
CreateDefaultBuilder()
:建立IWebHostBuilder
Build()
:IWebHostBuilder
負責建立IWebHost
Run()
:啟動IWebHost
所以,ASP.NET Core
應用的啟動本質上是啟動作為宿主的WebHost
物件。
其主要涉及到兩個關鍵物件IWebHostBuilder
和IWebHost
,它們的內部實現是ASP.NET Core
應用的核心所在。下面我們就結合原始碼並梳理呼叫堆疊來一探究竟!
2. 宿主構造器:IWebHostBuilder
在啟動IWebHost
宿主之前,我們需要完成對IWebHost的建立和配置。而這一項工作需要藉助IWebHostBuilder
物件來完成的,ASP.NET Core
中提供了預設實現WebHostBuilder
。而WebHostBuilder
是由WebHost
的同名工具類(Microsoft.AspNetCore
名稱空間下)中的CreateDefaultBuilder
方法建立的。
CreateDefaultBuilder()
呼叫堆疊
從上圖中我們可以看出CreateDefaultBuilder()
方法主要乾了六件大事:
UseKestrel
:使用Kestrel
作為Web server
。UseContentRoot
:指定Web host使用的content
root(內容根目錄),比如Views。預設為當前應用程式根目錄。ConfigureAppConfiguration
:設定當前應用程式配置。主要是讀取appsettinggs.json
配置檔案、開發環境中配置的UserSecrets
、新增環境變數和命令列引數 。ConfigureLogging
:讀取配置檔案中的Logging節點,配置日誌系統。UseIISIntegration
:使用IISIntegration
中介軟體。UseDefaultServiceProvider
:設定預設的依賴注入容器。
建立完畢WebHostBuilder
後,通過呼叫UseStartup()
來指定啟動類,來為後續服務的註冊及中介軟體的註冊提供入口。
3. 宿主:IWebHost
在ASP.Net Core中定義了IWebHost
用來表示Web
應用的宿主,並提供了一個預設實現WebHost
。宿主的建立是通過呼叫IWebHostBuilder
的Build()
方法來完成的。那該方法主要做了哪些事情呢,我們來看下面這張【ASP.NET Core啟動流程呼叫堆疊】中的黃色邊框部分:
ASP.NET Core啟動流程呼叫堆疊
其核心主要在於WebHost
的建立,又可以劃分為三個部分:
- 構建依賴注入容器,初始通用服務的註冊:
BuildCommonService();
- 例項化
WebHost
:var host = new WebHost(...);
- 初始化
WebHost
,也就是構建由中介軟體組成的請求處理管道:host.Initialize();
3.1. 註冊初始通用服務
BuildBuildCommonService
方法主要做了兩件事:
- 查詢
HostingStartupAttribute
特性以應用其他程式集中的啟動配置 - 註冊通用服務
- 若配置了啟動程式集,則發現並以
IStartup
型別注入到IOC
容器中
3.2. 建立IWebHost
public IWebHost Build()
{
//省略部分程式碼
var host = new WebHost(
applicationServices,
hostingServiceProvider,
_options,
_config,
hostingStartupErrors);
}
host.Initialize();
return host;
}
3.3. 構建請求處理管道
請求管道的構建,主要是中介軟體之間的銜接處理。
而請求處理管道的構建,又包含三個主要部分:
- 註冊
Startup
中繫結的服務; - 配置
IServer
; - 構建管道
請求管道的構建主要是藉助於IApplicationBuilder
,相關類圖如下:
請求管道的構建
4. 啟動WebHost
WebHost
的啟動主要分為兩步:
- 再次確認請求管道正確建立
- 啟動
Server
以監聽請求 - 啟動
HostedService
啟動WebHost
呼叫堆疊
4.1. 確認請求管道的建立
從圖中可以看出,第一步呼叫Initialize()
方法主要是取保請求管道的正確建立。其內部主要是對BuildApplication()
方法的呼叫,與我們上面所講WebHost
的構建環節具有相同的呼叫堆疊。而最終返回的正是由中介軟體銜接而成的RequestDelegate
型別代表的請求管道。
4.2. 啟動Server
我們先來看下類圖:
IServer
類圖
從類圖中我們可以看出IServer
介面主要定義了一個只讀的特性集合屬性、一個啟動和停止的方法宣告。在建立宿主構造器IWebHostBuilder
時我們通過呼叫UseKestrel()
方法指定了使用KestrelServer
作為預設的IServer
實現。其方法申明中接收了一個IHttpApplication<TContext> application
的引數,從命名來看,它代表一個Http
應用程式,我們來看下具體的介面定義:
IHttpApplication
類圖
其主要定義了三個方法,第一個方法用來建立請求上下文;第二個方法用來處理請求;第三個方法用來釋放上下文。而至於請求上下文,是用來攜帶請求和返回響應的核心引數,其貫穿與整個請求處理管道之中。ASP.NET Core
中提供了預設的實現HostingApplication
,其建構函式接收一個RequestDelegate _application
(也就是連結中介軟體形成的處理管道)用來處理請求。
var httpContextFactory = _applicationServices.GetRequiredService<IHttpContextFactory>();
var hostingApp = new HostingApplication(_application, _logger, diagnosticSource, httpContextFactory);
4.3. 啟動IHostedService
IHostedService
介面用來定義後臺任務,通過實現該介面並註冊到Ioc
容器中,它會隨著ASP.NET Core
程式啟動而啟動,終止而終止。
5. 總結
結合原始碼,通過對ASP.NET Core
執行呼叫堆疊的梳理,其啟動流程的總體脈絡一目瞭然,並且瞭解到主要的幾個關鍵物件:
- 負責建立
IWebHost
的宿主構造器IWebHostBuilder
- 代表宿主的
IWebHost
介面 - 用於構建請求管道的
IApplicationBuilder
- 中介軟體銜接而成的
RequestDelegate
- 代表
Web Server
的IServer
介面 - 貫穿請求處理管道的請求上下文
HttpContext
- 可以用來註冊後臺服務的
IHostedService
介面
相關文章
- Asp.net Core啟動流程講解(四)ASP.NET
- ASP.NET Core 啟動(1)ASP.NET
- 一張圖輕鬆掌握 Flink on YARN 應用啟動全流程(上)Yarn
- 【原始碼解讀】asp.net core原始碼啟動流程精細解讀原始碼ASP.NET
- 一張圖弄清Activity的啟動過程
- ASP.NET Core系列(三):啟動類StartupASP.NET
- ASP.NET Core使用HostingStartup增強啟動操作ASP.NET
- 《紅樓夢》人物關係有多複雜?一張圖幫你理清楚!
- ASP.NET core 2.2 截圖ASP.NET
- ASP.NET Core 3.x啟動時執行非同步任務(一)ASP.NET非同步
- app啟動流程,activity啟動流程時序圖,binder相關資料APP時序圖
- ASP.NET Core基礎知識(二)【應用啟動】ASP.NET
- 玩轉Elasticsearch原始碼-一圖看懂ES啟動流程Elasticsearch原始碼
- 【ASP.NET Core】MVC過濾器:執行流程ASP.NETMVC過濾器
- 一張流程圖 向你解釋 瀏覽器如何工作流程圖瀏覽器
- SpringBoot啟動流程分析原理(一)Spring Boot
- ASP.NET CORE中判斷是否移動端開啟網頁ASP.NET網頁
- ASP.NET Core 3.x控制IHostedService啟動順序淺探ASP.NET
- Activity 啟動流程學習總結(附原始碼流程圖)原始碼流程圖
- 頭禿了,二十三張圖帶你從原始碼瞭解Spring Boot 的啟動流程~原始碼Spring Boot
- 一張圖理清計算機常見編碼的關係。ASCII、Unicode都不是事兒計算機ASCIIUnicode
- 【asp.net core 系列】 1 帶你瞭解一下asp.net coreASP.NET
- SpringBoot原始碼解析-啟動流程(一)Spring Boot原始碼
- Android App應用啟動流程(一)AndroidAPP
- 征服Android面試官路漫漫(四):5 張圖帶你搞懂Android系統啟動的核心流程Android面試
- ASP.NET Core - 依賴注入(一)ASP.NET依賴注入
- ASP.NET Core-自動對映ASP.NET
- ASP.NET Core 3.x啟動時執行非同步任務(二)ASP.NET非同步
- Service啟動流程
- AMS啟動流程
- zygote啟動流程Go
- App啟動流程APP
- Flutter啟動流程Flutter
- linux啟動流程Linux
- IOC 啟動流程
- flowable 啟動流程
- kernel 啟動流程
- springboot啟動流程Spring Boot