【框架篇】Gin框架源码解读【更新中】
1.中间件
中间件的实现 依照设计模式中责任链模式,依次调用当前路由 注册的中间件
gin.go
// HandlerFunc defines the handler used by gin middleware as return value. type HandlerFunc func(*Context) // HandlersChain defines a HandlerFunc array. type HandlersChain []HandlerFunc
context.go
// Context is the most important part of gin. It allows us to pass variables between middleware, // manage the flow, validate the JSON of a request and render a JSON response for example. type Context struct { writermem responseWriter Request *http.Request Writer ResponseWriter Params Params handlers HandlersChain index int8 fullPath string engine *Engine params *Params // This mutex protect Keys map mu sync.RWMutex // Keys is a key/value pair exclusively for the context of each request. Keys map[string]interface{ } // Errors is a list of errors attached to all the handlers/middlewares who used this context. Errors errorMsgs // Accepted defines a list of manually accepted formats for content negotiation. Accepted []string // queryCache use url.ParseQuery cached the param query result from c.Request.URL.Query() queryCache url.Values // formCache use url.ParseQuery cached PostForm contains the parsed form data from POST, PATCH, // or PUT body parameters. formCache url.Values // SameSite allows a server to define a cookie attribute making it impossible for // the browser to send this cookie along with cross-site requests. sameSite http.SameSite }
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) c.index++ } }
Next() 这个方法只在中间件中使用有意义,调用后马上执行各个 handler(这些 handler 中包含你注册在路由上的方法),最后会返回到中间件。
c.Abort()
// Abort prevents pending handlers from being called. Note that this will not stop the current handler. // Lets say you have an authorization middleware that validates that the current request is authorized. // If the authorization fails (ex: the password does not match), call Abort to ensure the remaining handlers // for this request are not called. func (c *Context) Abort() { c.index = abortIndex }
让ctx当前index指向最后,直接返回
路由
context实现
下一篇:
JS高级之给数组扩展方法