- Engine
Engine即gin对应的服务端类(Server类),对应net/http中的ServeMux。编写gin的服务时,通常有两种初始化方法:
以上两种方法都生成一个*Engine实例,只是gin.Default()生成的Engine带了Logger和Recovery两个中间件。Engine的核心成员如下:
一个Engine的核心功能包括:
·注册路由
·给某个路由添加中间件
·接受新的连接
·当已有连接有数据来临时,调用对应路由下的处理函数(请求处理,此部分开启了单独的goroutine处理)
下面我们看一下对应的实现了以上功能的Engine函数。
注:Engine的路由和中间件注册对应在radix tree的添加节点,请求处理中的路由匹配部分对应在radix tree中查找节点。只要明白了radix tree的原理,这几个功能很好理解。而接受新的连接和连接到来时,调用请求处理函数则是复用了net/http的处理函数,参考上一章第一节部分。因此以下部分只介绍对应的函数和原理,不展示源码,以求提纲挈领。
路由注册和添加路由中间件
注册路由等功能是通过Engine下的RouterGroup实现的,RouterGroup实现了POST, GET,PUT, Group等函数。POST, GET,PUT, DELETE等函数就是在路由树radix_tree上添加一个路由节点;Group则是添加一个路由组,本质上就是在radix_tree上添加了一个非叶节点的路由节点。理解gin的路由实现,以上函数的原理理解起来就非常容易。中间件通过RouterGroup实现的Use函数添加。中间件函数的签名和请求处理函数一致,Use函数就是在RouterGroup.Handlers(HandlerFunc的数组)中添加一个中间件HandlerFunc。
接受新的连接
Engine的Run函数底层就是一个for循环,在循环内为每个新到来的连接创建一个goroutine(本质上是利用了net/http的ListenAndServe函数,实现对新连接的处理)
处理请求
Engine实现了ServeHTTP函数,从上一章1.3的分析中,我们知道ServeHTTP是统一的请求处理函数。ServeHTTP的主要作用就是在Engine.trees中找到跟请求路由对应的HandlersChain,并调用它们处理请求,回写结果(即路由匹配->请求处理->结果回写)。