2

gin flow 分析

  • Handler是如何注册和传递的?路由是如何解析的?http方法又是如何处理,使其满足RESTful规范的?这些细节都需要深入到代码层面来分析

辅助功能

  • 既然是框架,自然会处理各种项目中共性的问题,比如说404 Not Found。这部分框架的功能不是分析的重点。

启动http服务

  • 深入理解gin framework(一)的例子中,由r.Run(":14000")启动http服务。这里只能传入空值或者一个地址,否则会报错。源码如下,空值时默认端口为8080.

    clipboard.png

  • 启动http server的Run函数,TLS相似,只不过是加了个证书。其实还是把address传给官方标准包http的ListenAndServe函数,此处的engine struct只需要实现Handler接口,也就是实现ServeHTTP函数即可。

    clipboard.png

    clipboard.png

  • 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。
      clipboard.png
    • 当新的http请求过来的时候,调用getValue就可以找到对应path的handler。为什么没有对应的get,post方法呢?因为每个http方法自己一棵树~
      clipboard.png
  • OK。回到handleHTTPRequest函数中来。找到handler之后,把Context交给这个handler就行了,handler为什么能够处理Context呢?是因为这个:
    clipboard.png

番外:注册handler

  • 回到我们的例子

    clipboard.png
    clipboard.png
    clipboard.png

  • gin.Default()返回了一个Engine,这个engine继承了RouteGroup,而RouteGroup实现了IRouter接口(Get(),Post()...),所以r.Group("/api")其实调用的是RouteGroup函数
    clipboard.png
  • 在Group里边会整合handlers,计算并记录绝对路径。分组之后返回RouteGroup对象,此时,继续调用POST()函数,将handlerFunc和路径注册到对应的tree当中。具体如下:
    clipboard.png
    clipboard.png
    clipboard.png
    clipboard.png
  • 至此,会生成POST方法对应的tree,当有POST请求进入服务器时,找到POST tree,然后根据path找到对应的handler。再把已经初始化的Context交给相应的handler来处理。

Mandelbrot_Kobe
93 声望25 粉丝

golang