菜单

中间件系统

相关源文件

中间件系统是 Gin 框架的核心组件,它允许在 HTTP 请求生命周期中执行自定义代码。中间件函数在 HTTP 请求到达最终处理程序之前拦截它们,也可以在之后处理响应。本页介绍了 Gin 中间件系统的架构和用法,包括内置和自定义中间件组件。

有关特定内置中间件组件的信息,请参阅内置中间件

中间件概念和流程

Gin 中的中间件遵循基于链的执行模型,其中多个中间件函数按顺序组织。每个中间件都可以在链中的后续中间件之前和之后执行操作。

来源: context.go184-195

执行顺序

当请求到达时,Gin 按以下顺序执行中间件

  1. 每个中间件按添加的顺序执行
  2. 当中间件调用 c.Next() 时,控制权将传递给下一个中间件
  3. 到达链的末端(或最终处理程序)后,控制权将按相反顺序返回链
  4. 中间件函数中 c.Next() 调用之后的任何代码都将在返回路径上执行

理解中间件执行的关键在于,每个中间件函数都可以在链中的其余部分 *之前* 和 *之后* 执行代码。

来源: middleware_test.go17-43 context.go187-195

中间件注册

中间件可以全局注册(用于所有路由),为一组路由注册,或为特定路由注册。

来源: middleware_test.go17-43

核心中间件机制

中间件系统由 Gin 框架中的三个主要组件提供支持

  1. Context: 存储请求状态并提供流程控制方法
  2. HandlersChain: 中间件处理程序的有序切片
  3. Next/Abort 方法: 控制中间件链的流程

Context 和 HandlersChain

Gin 中的每个 HTTP 请求都通过一个 Context 对象进行处理,该对象包含一个 HandlersChain — 一个包含所有中间件和最终路由处理程序的处理程序切片。

Context 结构中的 index 字段跟踪中间件链中的当前位置。

来源: context.go57-93

流程控制方法

Gin 提供多种方法来控制中间件的执行流程

方法描述
c.Next()执行链中的待处理程序
c.Abort()阻止调用待处理程序
c.AbortWithStatus(code)中止并设置 HTTP 状态码
c.AbortWithStatusJSON(code, obj)中止并发送 JSON 响应
c.AbortWithError(code, err)中止并返回状态码和错误

来源: context.go184-232

内置中间件

Gin 提供多种内置中间件组件

日志中间件

Logger 中间件记录关于每个请求的信息,例如状态码、路径、延迟和客户端 IP。

来源: logger.go191-281

Recovery 中间件

Recovery 中间件可从处理程序链中的任何 panic 中恢复,并返回 500 错误,而不是使服务器崩溃。

来源: recovery.go32-104

创建自定义中间件

在 Gin 中创建自定义中间件需要定义一个返回 HandlerFunc 的函数

示例:身份验证中间件

中间件执行详情

处理请求时,中间件执行遵循以下步骤

  1. 从池中检索新的 Context
  2. 路由器找到匹配的处理程序(包括中间件)
  3. 使用 Next() 方法执行中间件链
  4. 每个中间件都可以
    • 在调用 Next() 之前执行代码
    • 调用 Next() 来执行链的其余部分
    • Next() 调用返回后执行代码
    • 调用 Abort() 来停止链的执行

来源: context.go184-195 middleware_test.go159-183

最佳实践

  • 顺序很重要:中间件按照其添加的顺序执行
  • 避免过多的中间件:每个中间件都会增加请求处理的开销
  • 保持中间件的专注:每个中间件应只有一个职责
  • 谨慎使用 abort:中止会阻止下游中间件执行
  • 妥善处理 panic:使用 Recovery 中间件或实现自己的 panic 恢复
  • 在中间件之间共享数据:使用 c.Set()c.Get() 在请求生命周期中传递数据

来源: context.go264-459 recovery.go32-104