Gin 路由和中间件调用链

GIN 使用中间件:

中间件是一个 HandlerFunc,接受多参数:

func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {
   engine.RouterGroup.Use(middleware...)
   engine.rebuild404Handlers()
   engine.rebuild405Handlers()
   return engine
}

把中间件维护到: group.Handlers

// Use adds middleware to the group, see example code in GitHub.
func (group *RouterGroup) Use(middleware ...HandlerFunc) IRoutes {
    group.Handlers = append(group.Handlers, middleware...)
    return group.returnObj()
}

添加路由

把 path 对应的 HandlerFunc append 到尾部, 再添加到路由树节点

func (group *RouterGroup) handle(httpMethod, relativePath string, handlers HandlersChain) IRoutes {
    absolutePath := group.calculateAbsolutePath(relativePath)
    handlers = group.combineHandlers(handlers)
    // 路由树,增加节点
    group.engine.addRoute(httpMethod, absolutePath, handlers)
    return group.returnObj()
}

访问路由

GIN 启动的时候,可以看到是调用了 net/http 包:

func (engine *Engine) Run(addr ...string) (err error) {
   defer func() { debugPrintError(err) }()

   trustedCIDRs, err := engine.prepareTrustedCIDRs()
   if err != nil {
      return err
   }
   engine.trustedCIDRs = trustedCIDRs
   address := resolveAddress(addr)
   debugPrint("Listening and serving HTTP on %s\n", address)
   // 此处把 engine 实例注入, 接管 http 处理
   err = http.ListenAndServe(address, engine)
   return
}

再看 net/http 实际处理请求的地方:

func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
    handler := sh.srv.Handler
    if handler == nil {
        handler = DefaultServeMux
    }
    if req.RequestURI == "*" && req.Method == "OPTIONS" {
        handler = globalOptionsHandler{}
    }
    // 可以看到这里 gin 接管了请求, 
    handler.ServeHTTP(rw, req)
}

gin处理请求, 实际调用的 c.Next()

// ServeHTTP conforms to the http.Handler interface.
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    c := engine.pool.Get().(*Context)
    c.writermem.reset(w)
    c.Request = req
    c.reset()

    engine.handleHTTPRequest(c)

    engine.pool.Put(c)
}

func (engine *Engine) handleHTTPRequest(c *Context) {
      root := t[i].root
      .....
      // Find route in tree
        value := root.getValue(rPath, c.params, unescape)
        c.Next()

      .....
}

func (c *Context) Next() {
   c.index++
   // 计算器循环调用
   for c.index < int8(len(c.handlers)) {
      c.handlers[c.index](c)
      c.index++
   }
}

debug 一下, 当访问 /blog/list 的时候, 在 tree 中找到的路由和对应的 handlers

Gin 路由和中间件调用链

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!