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

本作品采用《CC 协议》,转载必须注明作者和本文链接
 
           skyLee 的个人博客
 skyLee 的个人博客
         
           
           关于 LearnKu
                关于 LearnKu
               
                     
                     
                     粤公网安备 44030502004330号
 粤公网安备 44030502004330号 
 
推荐文章: