Gin的中间件依赖于责任链模式。
    不同中间件其实就是不同函数,通过gin.Use() 注册,并保存到gin上下文(Context)中的中间件数组中。

    1. r.Use(gin.LoggerWithWriter(gin.DefaultWriter, "/metrics", "/health"))
    2. r.Use(middleware.Recovery())
    1. // Use adds middleware to the group, see example code in GitHub.
    2. func (group *RouterGroup) Use(middleware ...HandlerFunc) IRoutes {
    3. group.Handlers = append(group.Handlers, middleware...)
    4. return group.returnObj()
    5. }
    1. // HandlersChain defines a HandlerFunc array.
    2. type HandlersChain []HandlerFunc

    当接收到请求后,匹配路由,该请求的所有信息都保存在Context中。
    中间件也不例外,接收到请求后,应查找所有应作用于该路由的中间件,保存在Context中,依次进行调用。

    在中间件的实现中,完成业务逻辑后,调用Next()方法去一次调用其余中间件。

    1. func (c *Context) Next() {
    2. c.index++
    3. for c.index < int8(len(c.handlers)) {
    4. c.handlers[c.index](c)
    5. c.index++
    6. }
    7. }