flask 原始碼解析 應用啟動流程

2021-09-17 19:37:50 字數 2867 閱讀 9823

文章屬於作者原創,原文發布在個人部落格。

所有的 python web 框架都要遵循 wsgi 協議,如果對 wsgi 不清楚,可以檢視我之前的介紹文章。

在這裡還是要簡單回顧一下 wsgi 的核心概念。

wsgi 的內容就講這麼多,我們來看看 flask 的 hello world 應用:

from flask import flask

def hello_world():

return 'hello, world!'

if __name__ == '__main__':

def run(self, host=none, port=none, debug=none, **options):

from werkzeug.serving import run_******

# 如果host 和 port 沒有指定,設定 host 和 port 的預設值 127.0.0.1 和 5000

if host is none:

host = '127.0.0.1'

if port is none:

server_name = self.config['server_name']

if server_name and ':' in server_name:

port = int(server_name.rsplit(':', 1)[1])

else:

port = 5000

# 呼叫 werkzeug.serving 模組的 run_****** 函式,傳入收到的引數

try:

run_******(host, port, self, **options)

finally:

self._got_first_request = false

try:

write(data)

if not headers_sent:

write(b'')

finally:

def __call__(self, environ, start_response):

"""# 建立請求上下文,並把它壓棧。這個在後面會詳細解釋

ctx = self.request_context(environ)

ctx.push()

error = none

try:

try:

# 正確的請求處理路徑,會通過路由找到對應的處理函式

response = self.full_dispatch_request()

except exception as e:

# 錯誤處理,預設是 internalservererror 錯誤處理函式,客戶端會看到伺服器 500 異常

error = e

response = self.handle_exception(e)

return response(environ, start_response)

finally:

if self.should_ignore_error(error):

error = none

# 不管處理是否發生異常,都需要把棧中的請求 pop 出來

ctx.auto_pop(error)

上面這段**只有乙個目的:找到處理函式,然後呼叫它。除了異常處理之外,我們還看到了context相關的內容(開始有ctx.push(),最後有ctx.auto_pop()的邏輯),它並不影響我們的理解,現在可以先不用管,後面會有一篇文章專門介紹。

繼續往後看,full_dsipatch_request的**如下:

這段**最核心的內容是dispatch_request,加上請求的 hooks 處理和錯誤處理的內容。

note:self.dispatch_request()返回的是處理函式的返回結果(比如 hello world 例子中返回的字串),finalize_request會把它轉換成response物件。

dispatch_request之前我們看到preprocess_request,之後看到finalize_request,它們裡面包括了請求處理之前和處理之後的很多 hooks 。這些 hooks 包括:

原始碼解析Flask的配置檔案

在flask裡,我們常在主檔案中定義某些配置,比如 實際上,flask中預設可以進行可選的配置項有很多。如果在開發的過程中,把所有需要的配置項都定義在主檔案中,就會造成整個程式的目錄結構不合理,如果需要重寫的flask配置項很多的時候,就可以把配置項用別的方式進行定義,然後匯入使用flask的配置檔...

Spring啟動並載入(原始碼解析)

二 流程 contextconfiglocation classpath config spring.xml org.springframework.web.context.contextloaderlistener package org.springframework.web.context p...

Activity啟動流程和原始碼解析

雙擊 markdown外掛程式,就可以開始編輯啦。public static void main string args 在attach方法中主要做了以下重要的事情 final iactivitymanager mgr activitymanager.getservice try catch rem...