gin框架分析二:gin初始化,默认配置实例构建过程
gin的函数调用流程
gin的函数调用过程大概如下图:

GIN函数调用过程第一步构建GIN实例,第二步构建GIN路由,第三步则是启动http.server包,坚挺HTTP请求,并将请求处理交给gin框架,gin又通过路由匹配寻找到对应的handler去具体处理每一个请求。
GIN的初始化过程
我们会从上面函数调用图的方法顺序开始过源码,并尝试弄清楚gin在各个阶段都干了些什么内容。
得到默认配置的gin实例
main函数代码中通过 gin.Default() 函数可以获取到一个默认配置的engine实例,Default()函数如下:
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())
return engine
}
debugPrintWARNINGDefault()函数首先被调用,其检测go版本是否在1.14+,如果不满足条件则给出一个警告,仅仅是一个警告而不做其他操作。
func debugPrintWARNINGDefault() {
if v, e := getMinVer(runtime.Version()); e == nil && v <= ginSupportMinGoVer {
debugPrint(`[WARNING] Now Gin requires Go 1.14+.
`)
}
debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
`)
}
通过调用New()函数,构造出一个默认配置项的engin实例。
func New() *Engine {
debugPrintWARNINGNew()
engine := &Engine{
RouterGroup: RouterGroup{
Handlers: nil,
basePath: "/",
root: true,
},
FuncMap: template.FuncMap{},
RedirectTrailingSlash: true,
RedirectFixedPath: false,
HandleMethodNotAllowed: false,
ForwardedByClientIP: true,
RemoteIPHeaders: []string{"X-Forwarded-For", "X-Real-IP"},
TrustedPlatform: defaultPlatform,
UseRawPath: false,
RemoveExtraSlash: false,
UnescapePathValues: true,
MaxMultipartMemory: defaultMultipartMemory,
trees: make(methodTrees, 0, 9),
delims: render.Delims{Left: "{{", Right: "}}"},
secureJSONPrefix: "while(1);",
trustedProxies: []string{"0.0.0.0/0", "::/0"},
trustedCIDRs: defaultTrustedCIDRs,
}
engine.RouterGroup.engine = engine
engine.pool.New = func() any {
return engine.allocateContext()
}
return engine
}
其中gin对于Context的处理使用了一个sync.Pool来处理,这样可以在每次对于Context的实例都不用重复生成,可以尽可能重复利用已经存在的实例。
engine.Use(Logger(), Recovery())方法默认为engine添加Logger和Recovery两个中间件,并保存于RouterGroup.Handlers中,然后在路由添加处理器是合并进各个路由处理中调用,这就是为什么通过gin.Default()生成实例后对于添加的路由处理方法会有3个handler的原因。
例如:
router.GET("/ping", func(c *gin.Context) {
c.String(200, "pong %d", counter)
counter = counter + 1
})
如上路由处理对应的路由信息为:

进入engine.Use(Logger(), Recovery())方法:
func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {
engine.RouterGroup.Use(middleware...)
engine.rebuild404Handlers()
engine.rebuild405Handlers()
return engine
}
其调用父类的Use方法把默认中间件添加到RouterGroup.Handlers,同时构建了404和405的异常处理钩子函数。
至此,gin.Defaults()创建了一个包含两个默认中间件、一个可重复利用Context并在Context实例不足时生成实例的gin engin,在获得默认配置的的gin实例后接下来的任务就是构建路由树和对应的处理方法。
本文来自博客园,作者:一朵野生菌,转载请注明原文链接:https://www.cnblogs.com/xmy20051643/p/17064132.html

浙公网安备 33010602011771号