参考资料
- https://study.163.com/course/courseMain.htm?courseId=1210171207 李文周Mooc
- https://www.liwenzhou.com/posts/Go/read_gin_sourcecode/#autoid-0-1-3 李文周博客
使用中间件程序示例
func main() {r := gin.Default()r.Use(func(context *gin.Context) {fmt.Printf("this is a middleware\n")})r.GET("/", func(c *gin.Context) {......}
中间件注册
Engine.Use
// 404,405也注册了中间件func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {engine.RouterGroup.Use(middleware...)engine.rebuild404Handlers()engine.rebuild405Handlers()return engine}
RouterGroup.Use
func (group *RouterGroup) Use(middleware ...HandlerFunc) IRoutes {// 直接在对应的路由组的Hanlers中添加对应方法group.Handlers = append(group.Handlers, middleware...)return group.returnObj()}
中间件的执行
路由匹配中执行以下代码
root := t[i].root// Find route in treevalue := root.getValue(rPath, c.params, unescape)if value.params != nil {c.Params = *value.params}if value.handlers != nil {c.handlers = value.handlersc.fullPath = value.fullPathc.Next()c.writermem.WriteHeaderNow()return}
其中c.Next()
func (c *Context) Next() {c.index++// 顺序执行Hanlers中的函数for c.index < int8(len(c.handlers)) {c.handlers[c.index](c)c.index++}}
中间件注册方式
func main() {// Default自带logger和recover中间件r := gin.Default()// 为根路径注册中间件(在所有处理函数之前调用)r.Use(func(context *gin.Context) {fmt.Printf("this is a middleware\n")})// 两种方式为路由组注册中间件shopGrout := r.Group("/shop", func1)shopGrout.Use(func2)......}
调用链的管理: c.Next(), c.Abort()
- 在某个处理方法中间调用c.Next()可以使之后的处理函数先执行,再执行该方法的剩余部分
- 在某个处理方法的中间使用c.Abort(),index值将被置为最大,后面的处理函数将不再执行
