gin框架源碼閱讀筆記:RouterGroup部分

engines包下:這個結構體是中間件和controller方法的格式:

type HandlerFunc func(*Context)

 

 

加粗部分是比較重要的變量/結構體,上下文一半會提到

 

RouterGroup相關:

路由組定義:

type RouterGroup struct {

Handlers HandlersChain

basePath string

engine *Engine

root bool

}

內含HandlersChain類型(上述HandlerFunc方法切片)字段Handlers用來保存當前路由組的函數鏈(即上述HandlerFunc切片

Use(middleware ...HandlerFunc)方法添加中間件/處理函數即用append方法向HandlerFunc切片添加一個HandlerFunc方法

func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc)即創建一個新的RouterGroup:

  • Handlers方法鏈字段爲原有鏈加上入參的方法鏈(創建了新切片:計算數量->copy原有->移動切片->copy入參),這裏做了長度限制,如果超出127/2的整數個數會拋出一個panic(爲什麼Use沒有做限制?)
  • basePath字段爲原有+入參的鏈接,調用了go的path.Join方法做了比較複雜判斷來保證兩個路徑前後‘/’在拼接時不重複,且以‘/’結尾
  • engine直接返回原engine對象指針
  • root採用默認值false,即既然調用該方法(不是函數),一定有調用者

BasePath()方法返回當前basePath

func (group *RouterGroup) handle(httpMethod, relativePath string, handlers HandlersChain)方法:內部方法,POST()、GET()、DELETE()等都由該方法實現

  • 計算新路徑(同Group方法),計算新方法鏈(同Group方法)
  • 調用engine的方法添加路由:group.engine.addRoute(“POST”/"GET".., 新路徑,新方法鏈),下邊有該方法大致介紹

GET, POST, PUT等方法都是直接調用 handle傳入本身類型字符串,路徑和方法鏈

Any方法即對所有已知類型調用一遍handle,接收該路由所有類型請求

Handle方法即 handle的對外方法,類型字符串只能由大寫A-Z組成

StaticFile(relativePathfilepath string)方法即把本地filepath路徑下的單個靜態文件當作服務提供給relativePath路由,包裝了go的http.ServeFile函數作爲處理器,註冊了GET和HEAD路由

Static(relativePath, root string)把root路徑下的文件當作靜態目錄作爲路由提供服務,不能使用通配符

  • 計算絕對路徑
  • 調用go的http.StripPrefix函數,實現把靜態目錄映射爲路由
  • 封裝http.FileSystem.Open(),Close(),httpServeHTTP()等函數作爲處理器
  • 加上/*filepath後綴(用於處理器中當作路徑取文件),註冊GET,HEAD類型的路由

StaticFS(relativePath string, fs http.FileSystem)函數和Static一樣,Static方法實際上是把root字符串通過go的http.Dir()函數包裝成http.FileSystem對象直接調用StaticFS實現的

engine相關:

addRoute(method, path string, handlers HandlersChain)方法:

從engine.trees(trees本身是一個methodTree切片,每個methodTree對象對應一種請求方法如POST,只包含“POST”字符串和根節點)中取出"POST"對應的樹根節點,從根節點根據路由找到(是一種基數樹,樹查找過程比較獨立,也很複雜,參考https://segmentfault.com/a/1190000019149860)相應位置,新建節點(包含全路由,方法鏈)插入樹

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章