参考资料
- 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 tree
value := root.getValue(rPath, c.params, unescape)
if value.params != nil {
c.Params = *value.params
}
if value.handlers != nil {
c.handlers = value.handlers
c.fullPath = value.fullPath
c.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值将被置为最大,后面的处理函数将不再执行