Gin源码分析

251 阅读4分钟

组成结构介绍

一、入口Engine

是gin框架的入口

Engine:Engine里有三个非常重要的数据

  • RouterGroup:使用Handlers存放中间件,另外提供设置路由的功能
  • pool:主要用于从池中获取或者存放Context,减少GC
  • trees:主要用于存放路由信息和该路由对应的处理函数列表,每个HTTP方法(GET POST等)都有单独的tree

常用的方法:

1724b145666b622b.png

还有一个ServerHttp方法,因为只有实现了这个方法,才能输入到http.ListenAndServe的第二个参数中去

二、RouteGroup

用于路由分组

会保存:

1、当前分组

2、handler 数组,因为要添加中间件

3、一个指针,一直指着 engine

常用方法

Use,添加中间件

三、Context

  1. Context:主要接收server传递过来的http.Request和http.Response,并对这两个数据进行处理
  2. 保存当前访问的所有需要处理的 handler,用一个数组保存

常用的方法:

Next() 方法,用于最后执行handler

初始化

gin.Default()

1、engine 的初始化分两步:

​ 第一步是New(),初始化engine 结构体 ;

​ 第二步是 添加中间件、创建全局的路由分组、给全局的路由分组添加中间件

image-20210226223426351.png

设置路由

1、调用 GET 方法设置路由,两个入参,一个是路由,一个是 handler,也是就是我们自己写的处理请求的方法,实际上是个切片的输入,可以输入多个handler;

2、GET方法实际上是在routerGroup中实现的,在添加路由的时候,一是需要计算出绝对路径;二是需要把之前所有的分组中的handler全部获取到,并和当前GET方法输入的handler合并到一个数组,最后把这些handler放在路由树的叶子节点处

3、实际上在设置路由的时候,会调用engine中的addRoute方法,需要先检查engine中有没有对应方法的路由树,如果没有,则需新建一个路由树,gin框架自己实现了路由算法,根据绝对路径生成对应方法的路由树,并把handler数组放到叶子节点处保存,同时路由树的节点会有一个标致,用来表示当前节点是否是最后一个节点,判断一条路由的结束。

image-20210226223531547.png

监听时

1、启动的方法是 engine 中的Run方法,这个方法实际上就是执行 http.ListenAndServe方法,这个方法有两个入参,一个是地址,也就是端口号,另外一个是 http包内部称为handler的接口,这个接口只有一个需要实现的方法,是ServerHttp,也就是说,实现了ServerHttp方法的结构体,就可以输入到第二个参数中,最后当请求来的时候,就会执行我们自己实现的ServerHttp方法

2、http包会监听请求,如果有请求来的话,会创建一个 goroutine 来处理

3、最后调用 gin 实现的ServerHttp方法来实现

image-20210226223625080.png

处理时

1、当请求到来后,调用ServeHttp方法去处理,该方法有两个参数,http.ReponseWriter 和 http.Request,前者用来最后输出的时候往 writer中写,request是请求的所有情况

2、在 gin 定义的 ServeHttp 方法中,首先会通过engine的pool获得一个可用的context ,然后将request和writer写到这个context中

3、然后去执行 engine中专门处理HTTP请求的方法,进入该方法后,先根据context中保存的request信息中的URL路径,来获取对应路径下的hanler数组(多个handler),然后把这些handler拷贝给context中的handlers,然后执行c.next()方法。

4、c.next()该方法是最终按之前路由中添加hanlder的顺序来执行handler,使用一个变量充当一个指针来指向具体执行的handler,每次调用next()方法,就会把这个index 变量+1,然后执行index下标的handler

5、释放 占用的 context

image-20210226223650602.png

结果返回

1、当执行我们自己写的处理handler时,会调用context包中的方法,比如String()方法,就是将结果转成字符串返回,返回的内容有 状态码,和具体信息

2、然后http包内部会调用打印方法,最后将结果输出反馈给客户端

image-20210226223703527.png

参考

www.processon.com/view/link/5…

www.processon.com/view/link/5…

juejin.cn/post/684490…