gin框架涉及中介軟體相關有4個常用的方法,它們分別是c.next()
、c.abort()
、c.set()
、c.get()
。
gin框架中的中介軟體設計很巧妙,我們可以首先從我們最常用的r := gin.default()
的default
函式開始看,它內部構造乙個新的engine
之後就通過use()
函式註冊了logger
中介軟體和recovery
中介軟體:
func setuprouter() *gin.engine
func default() *engine
繼續往下檢視一下use()
函式的**:
func (engine *engine) use(middleware ...handlerfunc) iroutes
從下方的**可以看出,註冊中介軟體其實就是將中介軟體函式追加到group.handlers
中:
func (group *routergroup) use(middleware ...handlerfunc) iroutes
而我們註冊路由時會將對應路由的函式和之前的中介軟體函式結合到一起:
func (group *routergroup) handle(httpmethod, relativepath string, handlers handlerschain) iroutes
其中結合操作的函式內容如下,注意觀察這裡是如何實現拼接兩個切片得到乙個新切片的。
const abortindex int8 = math.maxint8 / 2
func (group *routergroup) combinehandlers(handlers handlerschain) handlerschain
mergedhandlers := make(handlerschain, finalsize)
copy(mergedhandlers, group.handlers)
copy(mergedhandlers[len(group.handlers):], handlers)
return mergedhandlers
}
也就是說,我們會將乙個路由的中介軟體函式和處理函式結合到一起組成一條處理函式鏈條handlerschain
,而它本質上就是乙個由handlerfunc
組成的切片:
type handlerschain handlerfunc
我們在上面路由匹配的時候見過如下邏輯:
value := root.getvalue(rpath, c.params, unescape)
if value.handlers != nil
其中c.next()
就是很關鍵的一步,它的**很簡單:
func (c *context) next()
}
從上面的**可以看到,這裡通過索引遍歷handlerschain
鏈條,從而實現依次呼叫該路由的每乙個函式(中介軟體或處理請求的函式)。
我們可以在中介軟體函式中通過再次呼叫c.next()
實現巢狀呼叫(func1中呼叫func2;func2中呼叫func3),
或者通過呼叫c.abort()
中斷整個呼叫鏈條,從當前函式返回。
func (c *context) abort()
c.set()
和c.get()
這兩個方法多用於在多個函式之間通過c
傳遞資料的,比如我們可以在認證中介軟體中獲取當前請求的相關資訊(userid等)通過c.set()
存入c
,然後在後續處理業務邏輯的函式中通過c.get()
來獲取當前請求的使用者。c
就像是一根繩子,將該次請求相關的所有的函式都串起來了。
gin框架路由使用字首樹,路由註冊的過程是構造字首樹的過程,路由匹配的過程就是查詢字首樹的過程。
gin框架的中介軟體函式和處理函式是以切片形式的呼叫鏈條存在的,我們可以順序呼叫也可以借助c.next()
方法實現巢狀呼叫。
借助c.set()
和c.get()
方法我們能夠在不同的中介軟體函式中傳遞資料。
gin中介軟體講解
1 想要使用中介軟體必須是乙個 func c gin.context 型別的函式,底層實現了handefunc方法 2 中介軟體是請求和響應的分界點,無論怎麼變換給前端響應的那個動作永遠最後執行 2 use 法的作用是,將中介軟體函式存放到乙個map裡用於後續的執行,只會給c上下 新增 個屬性,並賦...
gin系列 中介軟體
gin框架允許開發者在處理請求的過程中,加入使用者自己的鉤子 hook 函式。這個鉤子函式就叫中介軟體,中介軟體適合處理一些公共的業務邏輯,比如登入認證 許可權校驗 資料分頁 記錄日誌 耗時統計等 定義中介軟體 gin中的中介軟體必須是乙個gin.handlerfunc型別 入門案例 定義乙個中介軟...
Gin 路由以及中介軟體
分組路由使 邏輯更加模組化,同時也易於定義中介軟體的使用範圍 v1 router.group v1 v1.get login func c gin.context v2 router.group v2 v2.get login func c gin.context 先定義乙個中介軟體函式 func ...