一個躺平程式員的回光返照,内容大部分是有道翻譯小部分是百度内容,如果有錯誤請在評論區提出,馬上改
直接貼代碼
// 設定運作模式 有三個值可選debug, release, test
gin.SetMode(utils.AppMode)
// 擷取架構引擎
r :=gin.Default()
// 自定義方法,綁定路由方法
initAdminRouter(r)
initMobileRouter(r)
// 運作
r.Run(":" + utils.HttpPort)
gin.SetMode
// SetMode sets gin mode according to input string.
// SetMode根據輸入字元串設定gin模式。
func SetMode(value string) {
if value == "" {
value = DebugMode
}
switch value {
case DebugMode: // debug
ginMode = debugCode
case ReleaseMode: // release
ginMode = releaseCode
case TestMode: // test
ginMode = testCode
default:
panic("gin mode unknown: " + value + " (available mode: debug release test)")
}
modeName = value
}
gin.Default()
debugPrintWARNINGDefault()
New()
Use()
Logger()
Recovery()
// Default returns an Engine instance with the Logger and Recovery middleware already attached.
// 預設傳回一個已經附加了Logger和Recovery中間件的引擎執行個體。
func Default() *Engine {
// 驗證go的版本号是否符合gin所需最低版本 go1.12+
debugPrintWARNINGDefault()
// 擷取一個引擎執行個體, 擷取的是引用類型執行個體
engine := New()
// 引擎執行個體bind Logger 和Recover中間件
engine.Use(Logger(), Recovery())
// 傳回執行個體
return engine
}
debugPrintWARNINGDefault
// ginSupportMinGoVer 預設值為 12
func debugPrintWARNINGDefault() {
if v, e := getMinVer(runtime.Version()); e == nil && v <= ginSupportMinGoVer {
debugPrint(`[WARNING] Now Gin requires Go 1.12+.
`)
}
debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
`)
}
// 輸入版本号go1.16.2傳回大版本号 16
func getMinVer(v string) (uint64, error) {
first := strings.IndexByte(v, '.')
last := strings.LastIndexByte(v, '.')
if first == last {
return strconv.ParseUint(v[first+1:], 10, 64)
}
return strconv.ParseUint(v[first+1:last], 10, 64)
}
New
// 傳回一個引擎執行個體(引用類型)
func New() *Engine {
// 提示資訊
debugPrintWARNINGNew()
// 擷取引擎執行個體
engine := &Engine{
// 初始化路由組
RouterGroup: RouterGroup{
// 路由組處理器
Handlers: nil,
basePath: "/",
root: true,
},
FuncMap: template.FuncMap{},
// 如果目前路由不能比對,但存在帶(不帶)尾斜杠的路徑處理程式,則啟用自動重定向。例如,如果/foo/被請求,但是/foo的路由隻存在,用戶端被重定向到/foo, GET請求的狀态碼是301,其他所有請求方法的狀态碼是307
RedirectTrailingSlash: true,
RedirectFixedPath: false,
HandleMethodNotAllowed: false,
//如果啟用,用戶端IP将從請求頭中解析,比對存儲在' (*gin.Engine). remoteipheaders '。
//如果沒有擷取IP,則傳回到從' (*gin.Context). request . remoteaddr '中擷取的IP。
ForwardedByClientIP: true,
// 啟用擷取用戶端IP(ForwardedByClientIP為true)且通過(TrustedProxies)時擷取指定頭部資訊。
RemoteIPHeaders: []string{"X-Forwarded-For", "X-Real-IP"},
TrustedProxies: []string{"0.0.0.0/0"},
// defaultAppEngine預設為false
AppEngine: defaultAppEngine,
// 啟用RawPath
UseRawPath: false,
RemoveExtraSlash: false,
// 如果為true,則不轉義路徑值。如果UseRawPath為false(預設情況下),則UnescapePathValues有效為true,如url.Path會被使用,它已經沒有轉義。
UnescapePathValues: true,
// 配置設定最大上傳大小 預設為32MB 32<<20
MaxMultipartMemory: defaultMultipartMemory,
// 建立長度為0的methodTrees切片且預留9個存儲空間
trees: make(methodTrees, 0, 9),
// 定義預設定界符
delims: render.Delims{Left: "{{", Right: "}}"},
secureJSONPrefix: "while(1);",
}
// 将初始化完成的引擎執行個體指派
engine.RouterGroup.engine = engine
/**
定義對象池(大概)并賦予預設值(大概,源碼中為)
if x == nil && p.New != nil {
x = p.New()
}
return x
*/
engine.pool.New = func() interface{} {
return engine.allocateContext()
}
return engine
}
// 配置設定Context(上下文) 傳回 Context(引用)
func (engine *Engine) allocateContext() *Context {
/**
Params為 []type Param struct {
Key string
Value string
}
engine.maxParams 預設為0
*/
v := make(Params, 0, engine.maxParams)
return &Context{engine: engine, params: &v}
}
Use
// Engine的Use方法,不定參,參數的類型為HandlerFunc 傳回IRoutes
func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {
engine.RouterGroup.Use(middleware...)
// 建構404請求 noRoute
engine.rebuild404Handlers()
// 建構405請求 noMethod
engine.rebuild405Handlers()
return engine
}
// RouteGroup.Use
// 在RouteGroup中添加處理程式(中間件) IRoutes
func (group *RouterGroup) Use(middleware ...HandlerFunc) IRoutes {
// Handlers是Group中的處理程式存儲屬性
group.Handlers = append(group.Handlers, middleware...)
return group.returnObj()
}
Logger
// 剛看到這兒的時候我還在想他是怎麼實作的 HandlerFunc定義為 type HandlerFunc func(*Context),看完代碼發現我是真的蠢
// 傳回一個HandlerFunc
func Logger() HandlerFunc {
return LoggerWithConfig(LoggerConfig{})
}
// LoggerWithConfig instance a Logger middleware with config.
// LoggerWithConfig執行個體是一個帶有config的Logger中間件。
// 傳回值是一個HandleFunc
func LoggerWithConfig(conf LoggerConfig) HandlerFunc {
// 代碼略過,架構主體走完在看這些中間件具體實作
// ...
// 傳回一個匿名方法 666 果然人與人之間是不一樣的
return func(c *Context) {
}
}
Recovery
func Recovery() HandlerFunc {
return RecoveryWithWriter(DefaultErrorWriter)
}
// RecoveryWithWriter returns a middleware for a given writer that recovers from any panics and writes a 500 if there was one.
RecoveryWithWriter為給定的寫入器傳回一個中間件,該中間件可以從任何panics中恢複,如果有panics,則寫入一個500。
func RecoveryWithWriter(out io.Writer, recovery ...RecoveryFunc) HandlerFunc {
// 如果傳了後續參數則使用,如果沒有則使用預設參, 預設參的一種實作方式
if len(recovery) > 0 {
return CustomRecoveryWithWriter(out, recovery[0])
}
return CustomRecoveryWithWriter(out, defaultHandleRecovery)
}
// CustomRecoveryWithWriter returns a middleware for a given writer that recovers from any panics and calls the provided handle func to handle it.
func CustomRecoveryWithWriter(out io.Writer, handle RecoveryFunc) HandlerFunc {
var logger *log.Logger
if out != nil {
logger = log.New(out, "\n\n\x1b[31m", log.LstdFlags)
}
return func(c *Context) {
// 延遲執行 最後執行, 如果多個defer則按棧的規則先進後出
// 入 func(1) func(2) func(3)
// 出 3 2 1
defer func() {
// ...
}()// 匿名方法立即執行方法
// c為Context Next()為繼續執行下一個處理方法(大概)
c.Next()
}
}
// c.Next() 将handlers中的方法依次執行
func (c *Context) Next() {
c.index++
for c.index < int8(len(c.handlers)) {
c.handlers[c.index](c)
c.index++
}
}