gin中间件详解及原理分析
gin中间件详解
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"time"
)
func main() {
r := gin.New()
// 使用Logger和Recovery中间件
r.Use(gin.Logger())
r.Use(gin.Recovery())
// 使用自定义中间件,中间件既可以应用在某个url上,也可以应用在某个组上,也可以应用在全局所有url上
authorized := r.Group("/admin", TokenRequired(), MyLogger())
authorized.GET("/home", func(context *gin.Context) {
time.Sleep(time.Millisecond * 380)
v, _ := context.Get("example")
context.JSON(http.StatusOK, gin.H{"message": "home", "example": v})
})
r.GET("/index", func(context *gin.Context) {
time.Sleep(time.Millisecond * 1380)
context.JSON(http.StatusOK, gin.H{"message": "index"})
})
r.Run()
}
func MyLogger() gin.HandlerFunc {
// 统计执行时长中间件
return func(context *gin.Context) {
start := time.Now()
context.Set("example", "123456") // 中间件中添加变量值
// 让原本该执行的逻辑继续执行
context.Next()
fmt.Println(time.Since(start))
// 获取函数执行完后的状态
status := context.Writer.Status()
fmt.Printf("状态:%v\n", status)
}
}
func TokenRequired() gin.HandlerFunc {
return func(context *gin.Context) {
//token := context.GetHeader("x-token")
// 获取token
var token string
for key, value := range context.Request.Header {
if key == "X-Token" {
token = value[0]
break
}
}
// 判定token
if token != "x-sankuan"{
context.JSON(http.StatusUnauthorized, gin.H{
"err": "unauthorized",
"detail": "token认证失败",
})
// return 挑战,为什么return都阻止不了后续逻辑的执行
context.Abort() // 终止中间件后续逻辑的执行
}
context.Next()
}
}
原理分析
因为gin的中间件函数与业务逻辑处理函数是放到gin的队列中的
所以当一个中间件函数执行return语句时只代表当前中间件函数执行完了,gin框架会驱动index++,然后执行队列中后续的中间件函数或逻辑处理函数
当在中间件函数中执行context.Next()时,源码如下
func (c *Context) Next() {
c.index++
for c.index < int8(len(c.handlers)) {
c.handlers[c.index](c)
c.index++
}
}
队列中的index会执行+1操作,然后调用c.handlersc.index,也就是调用队列中后面的一个函数,
当执行context.Abort()时,源码如下:
func (c *Context) Abort() {
c.index = abortIndex
}
会修改c.index = 63.5,由于该索引不存在,所以队列中后面的的中间件函数和逻辑处理函数就不会执行了。
分类:
gin
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)