gin flow 分析
- Handler是如何注册和传递的?路由是如何解析的?http方法又是如何处理,使其满足RESTful规范的?这些细节都需要深入到代码层面来分析
辅助功能
- 既然是框架,自然会处理各种项目中共性的问题,比如说404 Not Found。这部分框架的功能不是分析的重点。
启动http服务
- 在深入理解gin framework(一)的例子中,由r.Run(":14000")启动http服务。这里只能传入空值或者一个地址,否则会报错。源码如下,空值时默认端口为8080.
- 启动http server的Run函数,TLS相似,只不过是加了个证书。其实还是把address传给官方标准包http的ListenAndServe函数,此处的engine struct只需要实现Handler接口,也就是实现ServeHTTP函数即可。
- engine struct中的pool就是sync.Pool,代码中可以看出来,每处理一个http请求,都会从连接池里边取出一个Context,把请求参数传递给这个Context,处理完之后,再把这个Context放回去。
处理http请求
- 从上边的源码可以看出来,所有的http请求都会走到handleHTTPRequest函数中去处理。
- handleHTTPRequest处理的第一步是初始化Context的参数,前面有说到,Context结构体封装了处理http请求的所有数据。初始化参数就是将Context里面的数据更新为此次http请求的数据,方便接下来对Context进行处理。
-
想要理解接下来handleHTTPRequest的处理逻辑,需要先岔开到tree.go文件当中去。
- 确定某次http请求怎么处理,需要明确审什么?三件事情,path,method,handler!
- 在tree文件当中,以基数树的结构存储了path,及其该path对应的handler。
- 当新的http请求过来的时候,调用getValue就可以找到对应path的handler。为什么没有对应的get,post方法呢?因为每个http方法自己一棵树~
- OK。回到handleHTTPRequest函数中来。找到handler之后,把Context交给这个handler就行了,handler为什么能够处理Context呢?是因为这个:
番外:注册handler
- 回到我们的例子。
- gin.Default()返回了一个Engine,这个engine继承了RouteGroup,而RouteGroup实现了IRouter接口(Get(),Post()...),所以r.Group("/api")其实调用的是RouteGroup函数
- 在Group里边会整合handlers,计算并记录绝对路径。分组之后返回RouteGroup对象,此时,继续调用POST()函数,将handlerFunc和路径注册到对应的tree当中。具体如下:
- 至此,会生成POST方法对应的tree,当有POST请求进入服务器时,找到POST tree,然后根据path找到对应的handler。再把已经初始化的Context交给相应的handler来处理。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。