https://blog.csdn.net/HideonHacker/article/details/138095563

Gin官网文档地址:https://gin-gonic.com/zh-cn/docs

Gin 是在 Golang HTTP 标准库 net/http 基础之上的再封装,即Gin的底层还是http的实现,但是新增了gin.Engine对象,作为Handler注入,从而实现路由的注册和匹配、请求处理的链路优化。

Gin框架特点

  • 支持中间件操作( handlersChain 机制 )
  • 更方便的使用( gin.Context )
  • 更强大的路由解析能力( radix tree 路由树 )

简单的gin实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main() {
// 创建一个 gin Engine,本质上是一个 http Handler,即实现了ServeHTTP方法,实现地址跟HnadleFunc的匹配
mux := gin.Default()
// 注册中间件,中间件是在HandleFunc执行前或者执行后执行的方法,与JavaSpring框架的AOP相类似
mux.Use(myMiddleWare)
// 注册一个 path 为 /ping 的处理函数
// “/Ping” 为路由,func == HandleFunc
mux.POST("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, "pone")
})
// 运行 http 服务
// 监听8080端口
if err := mux.Run(":8080"); err != nil {
panic(err)
}
}

处理请求
在服务端接收到 http 请求时,会通过 Handler.ServeHTTP 方法进行处理. 而此处的 Handler 正是 gin.Engine,其处理请求的核心步骤如下:

对于每笔 http 请求,会为其分配一个 gin.Context,在 handlers 链路中持续向下传递
调用 Engine.handleHTTPRequest 方法,从路由树中获取 handlers 链,然后遍历调用
处理完 http 请求后,会将 gin.Context 进行回收. 整个回收复用的流程基于对象池管理

https://blog.csdn.net/HideonHacker/article/details/138095563

Gin官网文档地址:https://gin-gonic.com/zh-cn/docs

Gin 是在 Golang HTTP 标准库 net/http 基础之上的再封装,即Gin的底层还是http的实现,但是新增了gin.Engine对象,作为Handler注入,从而实现路由的注册和匹配、请求处理的链路优化。

Gin框架特点

  • 支持中间件操作( handlersChain 机制 )
  • 更方便的使用( gin.Context )
  • 更强大的路由解析能力( radix tree 路由树 )

简单的gin实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main() {
// 创建一个 gin Engine,本质上是一个 http Handler,即实现了ServeHTTP方法,实现地址跟HnadleFunc的匹配
mux := gin.Default()
// 注册中间件,中间件是在HandleFunc执行前或者执行后执行的方法,与JavaSpring框架的AOP相类似
mux.Use(myMiddleWare)
// 注册一个 path 为 /ping 的处理函数
// “/Ping” 为路由,func == HandleFunc
mux.POST("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, "pone")
})
// 运行 http 服务
// 监听8080端口
if err := mux.Run(":8080"); err != nil {
panic(err)
}
}

处理请求

在服务端接收到 http 请求时,会通过 Handler.ServeHTTP 方法进行处理. 而此处的 Handler 正是 gin.Engine,其处理请求的核心步骤如下:

  1. 对于每笔 http 请求,会为其分配一个 gin.Context,在 handlers 链路中持续向下传递
  2. 调用 Engine.handleHTTPRequest 方法,从路由树中获取 handlers 链,然后遍历调用
  3. 处理完 http 请求后,会将 gin.Context 进行回收. 整个回收复用的流程基于对象池管理

自定义中间件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
func Logger() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()

// 设置 example 变量
c.Set("example", "12345")

// 请求前

c.Next()

// 请求后
latency := time.Since(t)
log.Print(latency)

// 获取发送的 status
status := c.Writer.Status()
log.Println(status)
}
}

func main() {
r := gin.New()
r.Use(Logger())

r.GET("/test", func(c *gin.Context) {
example := c.MustGet("example").(string)

// 打印:"12345"
log.Println(example)
})

// 监听并在 0.0.0.0:8080 上启动服务
r.Run(":8080")
}

常用自定义中间件 超时 加密校验 读取通用参数

Gin路由树

路由树的数据结构是压缩前缀树
压缩前缀树又称基数树或 radix 树,是对前缀树的改良版本,优化点主要在于空间的节省,核心策略体现在:
倘若某个子节点是其父节点的唯一孩子,则与父节点进行合并

总结

  • gin 将 Engine 作为 http.Handler 的实现类进行注入,从而融入 Golang net/http 标准库的框架之内
  • gin 中基于 handler 链的方式实现中间件和处理函数的协调使用
  • gin 中基于压缩前缀树的方式作为路由树的数据结构,对应于 9 种 http 方法共有 9 棵树
  • gin 中基于 gin.Context 作为一次 http 请求贯穿整条 handler chain 的核心数据结构
  • gin.Context 是一种会被频繁创建销毁的资源对象,因此使用对象池 sync.Pool 进行缓存复用