gin的函数调用过程大概如下图:
GIN函数调用过程第一步构建GIN实例,第二步构建GIN路由,第三步则是启动http.server包,坚挺HTTP请求,并将请求处理交给gin框架,gin又通过路由匹配寻找到对应的handler去具体处理每一个请求。
GIN的初始化过程我们会从上面函数调用图的方法顺序开始过源码,并尝试弄清楚gin在各个阶段都干了些什么内容。
得到默认配置的gin实例
main函数代码中通过 gin.Default() 函数可以获取到一个默认配置的engine实例,Default()函数如下:
debugPrintWARNINGDefault()函数首先被调用,其检测go版本是否在1.14+,如果不满足条件则给出一个警告,仅仅是一个警告而不做其他操作。
通过调用New()函数,构造出一个默认配置项的engin实例。
其中gin对于Context的处理使用了一个sync.Pool来处理,这样可以在每次对于Context的实例都不用重复生成,可以尽可能重复利用已经存在的实例。
engine.Use(Logger(), Recovery())方法默认为engine添加Logger和Recovery两个中间件,并保存于RouterGroup.Handlers中,然后在路由添加处理器是合并进各个路由处理中调用,这就是为什么通过gin.Default()生成实例后对于添加的路由处理方法会有3个handler的原因。
例如:
如上路由处理对应的路由信息为:
进入engine.Use(Logger(), Recovery())方法:
其调用父类的Use方法把默认中间件添加到RouterGroup.Handlers,同时构建了404和405的异常处理钩子函数。
至此,gin.Defaults()创建了一个包含两个默认中间件、一个可重复利用Context并在Context实例不足时生成实例的gin engin,在获得默认配置的的gin实例后接下来的任务就是构建路由树和对应的处理方法。