gin.Default() 默认包含 gin.Logger() 和 gin.Recovery() 两个中间件,自动启用请求日志打印和 panic 捕获;而 gin.New() 不带任何中间件,需手动 Use() 添加并控制顺序。

gin.Default() 自带哪些中间件?
它默认包含 gin.Logger() 和 gin.Recovery() 两个中间件,不用手动 Use() 就能生效。这意味着:请求日志会自动打印到终端,panic 会被捕获并返回 500,服务不会因此崩溃。
但要注意:gin.New() 不带任何中间件,完全空白——如果你需要日志或 panic 恢复,必须显式调用 Use() 添加。
-
gin.Default()适合开发和简单场景,开箱即用 -
gin.New()更适合生产环境定制,比如想替换默认日志格式、禁用 recovery 或插入自定义前置逻辑 - 一旦用了
gin.New(),Logger和Recovery就得自己加,顺序也得自己控制(Recovery通常放最后)
如何注册全局中间件?
用 r.Use() 注册的中间件对所有路由生效,执行顺序就是代码里 Use() 的调用顺序。比如:
func main() {
r := gin.New()
r.Use(middleware1)
r.Use(middleware2)
r.Use(gin.Recovery())
r.GET("/ping", handler)
}
请求进来时,先执行 middleware1 前半段 → middleware2 前半段 → gin.Recovery() 前半段 → 最终 handler → 再按相反顺序执行各中间件后半段(洋葱模型)。
立即学习“go语言免费学习笔记(深入)”;
- 中间件函数签名必须是
func(*gin.Context),否则编译不通过 - 别忘了在需要继续链路的地方调用
c.Next(),否则后续中间件和 handler 都不会执行 - 如果某个中间件决定终止流程(如鉴权失败),要用
c.Abort(),它会跳过后续所有中间件和 handler
路由分组怎么配中间件?
用 r.Group("/admin", authMiddleware, logMiddleware) 这种方式,只对这个分组下的子路由生效。分组中间件优先于全局中间件执行(但仍在全局中间件链内,只是位置靠前)。
常见误操作是把中间件写成 adminGroup.Use(authMiddleware) ——这其实等价于全局注册,因为 Use() 是往 engine 上挂,不是 group 独有。
- 分组中间件参数直接传进
Group()第二个及之后的参数,类型是gin.HandlerFunc - 多个中间件按从左到右顺序执行,和
Use()一致 - 分组嵌套时,外层分组的中间件会先于内层分组的中间件执行
自定义中间件里怎么安全读写 context?
中间件之间通过 c.Set() / c.MustGet() / c.Get() 共享数据,但必须注意类型断言和存在性检查。
比如 c.MustGet("user_id").(string) 在 key 不存在或类型不匹配时会 panic;而 v, ok := c.Get("user_id") 更安全,适合不确定是否设置过的地方。
- 避免在中间件里直接修改
c.Request或c.Writer,除非你清楚副作用(比如提前写响应会导致后续 handler 报错) - 异步操作(如 goroutine 日志上报)必须用
c.Copy(),否则原 context 可能在 handler 返回后被回收 - 不要在中间件里重复调用
c.Next(),会导致 handler 执行两次甚至死循环


















