Gin是一个用Go编写的web框架,我们来看一下Gin的请求生命周期。有助于了解Gin的执行原理和开发。
1、Gin服务执行流程
启动一个简单的的Gin http服务:
package main
import "github.com/gin-gonic/gin"
func main() {
// 创建 Gin Engine 实例
r := gin.Default()
// 设置请求 URI /ping 的路由及响应处理函数
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
// 启动 Web 服务,监听端口,等待 HTTP 请求到并生成响应
r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}
通过执行go run main.go命令来运行代码,它会启动一个阻塞进程监听并等待HTTP请求:
从代码中我们看出通过Gin实现一个最简单的Web服务器,只需要三个步骤:
- 创建Gin实例
- 注册路由及处理函数
- 启动Web服务
执行流程图如下:
2、Gin生命周期
2.1、创建Gin实例
Gin实例创建通过Gin.Default()方法实现,其定义如下:
func Default() *Engine {
//调试模式日志输出
debugPrintWARNINGDefault()
//创建一个gin框架实例
engine := New()
//注册中间件,中间件是一个函数,最终只要返回一个type HandlerFunc func(*Context)就可以
engine.Use(Logger(), Recovery())
return engine
}
Default()方法实现如下功能:
- 创建Gin框架对象Engine
- 配置Gin默认的中间件
- 返回Gin框架对象
2.2、注册路由
以 gin.GET 为例,开展源码如下:
// GET is a shortcut for router.Handle("GET", path, handle).
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle(http.MethodGet, relativePath, handlers)
}
路由注册,实际上是调用了RouterGroup的Get方法,RouterGroup实现了IRoutes interface, RouterGroup主要提供路由注册功能。
type RouterGroup struct {
Handlers HandlersChain
basePath string
engine *Engine
root bool
}
2.3、接收请求并响应
Gin实例化和路由注册工作后,然后进入Gin声明周期外围功能分析,Gin到底是如何启动Web服务,监听HTTP请求处理函数生成响应的,这些工作是从Gin.Run实现的。
func (engine *Engine) Run(addr ...string) (err error) {
defer func() { debugPrintError(err) }()
address := resolveAddress(addr)
debugPrint("Listening and serving HTTP on %s\n", address)
//执行http包的ListenAndServe方法,启动路由
//engine实现了http.Handler接口,所以在这里作为参数穿进去
err = http.ListenAndServe(address, engine)
return
}
gin.Run是net/http标准库http.ListenAndServe的简写,功能是将路由连接到http.Server启动并监听HTTP请求。
本文正在参加技术专题18期-聊聊Go语言框架