欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解Go Gin框架中間件的實現(xiàn)原理

 更新時間:2023年09月25日 09:41:12   作者:水洗牛仔褲  
在Go Gin框架中,中間件是一種在請求處理過程中插入的功能模塊,它可以用于處理請求的前置和后置邏輯,例如認(rèn)證、日志記錄、錯誤處理等,本文將給大家介紹一下Go Gin框架中間件的實現(xiàn)原理,需要的朋友可以參考下

中間件的實現(xiàn)原理

中間件的實現(xiàn)有:鏈?zhǔn)秸{(diào)用, 攔截器,注冊中心等方式,Gin框架使用的是 鏈?zhǔn)秸{(diào)用洋蔥模型 。

鏈?zhǔn)秸{(diào)用

鏈?zhǔn)秸{(diào)用,顧名思義就是像一個鏈子一樣連在一起,一個一個的別調(diào)用。

Gin框架中的是一個切片:

// HandlerFunc將gin中間件使用的處理程序定義為返回值。
type HandlerFunc func(*Context)
//HandlersChain定義HandlerFunc切片。
type HandlersChain []HandlerFunc

一個路由需要經(jīng)歷的所有中間件函數(shù)以及最終的處理函數(shù)都會被按照添加的順序添加到函數(shù)鏈中并儲存在路由樹的節(jié)點上。

怎么調(diào)用中間件

在Gin中實現(xiàn)了http包的Handler接口的ServerHTTP方法,(調(diào)用流程在Gin啟動和接收請求的文章中介紹)。經(jīng)過ServerHTTP方法,初始化了Context結(jié)構(gòu)體,給其中index這個字段設(shè)為-1,調(diào)用c.Next時會調(diào)用到中間件函數(shù)。

ServerHTTP

// ServeHTTP實現(xiàn)http.Handler接口。
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	c := engine.pool.Get().(*Context)
	c.writermem.reset(w)
	c.Request = req
	c.reset()//初始化Context
	engine.handleHTTPRequest(c)//在這里邊調(diào)用了c.Next(),
	engine.pool.Put(c)
}

c.Next

// Next should be used only inside middleware.
// It executes the pending handlers in the chain inside the calling handler.
// See example in GitHub.
func (c *Context) Next() {
	c.index++
	for c.index < int8(len(c.handlers)) {
		c.handlers[c.index](c)//這個就是函數(shù)鏈,調(diào)用第index的函數(shù),參數(shù)為c。
		c.index++
	}
}

c.Abort

在中間件中還有一個Abort函數(shù),作用是終止執(zhí)行。

// Abort阻止調(diào)用掛起的處理程序。請注意,這不會停止當(dāng)前處理程序。
//假設(shè)你有一個授權(quán)中間件,它驗證當(dāng)前請求是否被授權(quán)。
//如果授權(quán)失?。ɡ纾好艽a不匹配),
//則調(diào)用Abort以確保不調(diào)用此請求的其余處理程序。
const abortIndex int8 = math.MaxInt8 >> 1
func (c *Context) Abort() {
	c.index = abortIndex
}

洋蔥模型

就像這個洋蔥一樣,鏈?zhǔn)胶瘮?shù)是一層一層的調(diào)用的。

我們看一下Gin框架官方的兩個中間件,他們很好的體現(xiàn)了洋蔥模型。

func Default() *Engine {
	debugPrintWARNINGDefault()
	engine := New()
	engine.Use(Logger(), Recovery())
	return engine
}

Logger

func Logger() HandlerFunc {
	return LoggerWithConfig(LoggerConfig{})
}
func LoggerWithConfig(conf LoggerConfig) HandlerFunc {
	//省略初始化日志。
	return func(c *Context) {
	...
		c.Next()
		//省略將日志格式化輸出
		}
	}
}

通過前面我們知道,調(diào)用c.Next函數(shù)的時候會調(diào)用下一個函數(shù)鏈中下一個函數(shù),這時候LoggerWithConfig函數(shù)還沒有執(zhí)行完,就開始執(zhí)行下一個函數(shù)了,當(dāng)這個c.Next執(zhí)行完成后,才會去執(zhí)行下面的語句了。這個過程是不是就像是一層包一層,類似于洋蔥一樣。

Recovery

func Recovery() HandlerFunc {
	return RecoveryWithWriter(DefaultErrorWriter)
}
func RecoveryWithWriter(out io.Writer, recovery ...RecoveryFunc) HandlerFunc {
	if len(recovery) > 0 {
		return CustomRecoveryWithWriter(out, recovery[0])
	}
	return CustomRecoveryWithWriter(out, defaultHandleRecovery)
}
func CustomRecoveryWithWriter(out io.Writer, handle RecoveryFunc) HandlerFunc {
	...
	return func(c *Context) {
		defer func() {
			//基本功能是去捕獲異常的
		}()
		c.Next()
	}
}

Recovery的做作用是捕獲異常的,defer后的函數(shù)的作用是去捕獲c.Next函數(shù)后的異常,防止程序崩潰。具體原理可以去看看defer,painc和recovery的運行機制。

到此這篇關(guān)于深入理解Go Gin框架中間件的實現(xiàn)原理的文章就介紹到這了,更多相關(guān)Go Gin框架中間件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang多線程排序?qū)崿F(xiàn)快速高效地處理大規(guī)模數(shù)據(jù)

    Golang多線程排序?qū)崿F(xiàn)快速高效地處理大規(guī)模數(shù)據(jù)

    Golang多線程排序是一種快速高效地處理大規(guī)模數(shù)據(jù)的方法,通過使用Golang的協(xié)程和通道,可以將排序任務(wù)分配到多個線程中并行處理,提高了排序的效率和速度,需要詳細(xì)了解可以參考下文
    2023-05-05
  • Go中如何使用set的方法示例

    Go中如何使用set的方法示例

    這篇文章主要介紹了Go中如何使用set的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 詳解Go多協(xié)程并發(fā)環(huán)境下的錯誤處理

    詳解Go多協(xié)程并發(fā)環(huán)境下的錯誤處理

    這篇文章主要介紹了詳解Go多協(xié)程并發(fā)環(huán)境下的錯誤處理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 詳解Go 并發(fā)

    詳解Go 并發(fā)

    這篇文章主要介紹了Go 并發(fā)的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)go語言,感興趣的朋友可以了解下
    2020-09-09
  • Go語言正則表達(dá)式示例

    Go語言正則表達(dá)式示例

    這篇文章主要介紹了Go語言正則表達(dá)式,結(jié)合實例形式分析了Go語言正則表達(dá)式實現(xiàn)字符串的匹配、查找等相關(guān)操作技巧,需要的朋友可以參考下
    2017-01-01
  • golang包快速生成base64驗證碼的方法

    golang包快速生成base64驗證碼的方法

    這篇文章主要介紹了golang包快速生成base64驗證碼的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • golang中"var"與":="的區(qū)別解析

    golang中"var"與":="的區(qū)別解析

    這篇文章主要介紹了golang中“var”與“:=”的區(qū)別,使用var關(guān)鍵字是Go最基本的定義變量方式,有時也會使用到:=來定義變量,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • Go語言集成開發(fā)環(huán)境IDE詳細(xì)安裝教程

    Go語言集成開發(fā)環(huán)境IDE詳細(xì)安裝教程

    VSCode是免費開源的現(xiàn)代化輕量級代碼編輯器,支持幾乎所有主流的開發(fā)語言,內(nèi)置命令行工具和 Git 版本控制系統(tǒng),支持插件擴展,這篇文章主要介紹了Go語言集成開發(fā)環(huán)境IDE詳細(xì)安裝教程,需要的朋友可以參考下
    2021-11-11
  • Gotify搭建你的消息推送系統(tǒng)

    Gotify搭建你的消息推送系統(tǒng)

    這篇文章主要介紹了Gotify搭建你的消息推送系統(tǒng),今天要分享的是 gotify,是一個用 go 編寫的消息服務(wù)端,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2024-01-01
  • gin 獲取post請求的json body操作

    gin 獲取post請求的json body操作

    這篇文章主要介紹了gin 獲取post請求的json body操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03

最新評論