• gin.New() 函数中我们可以看到 basePath 默认是 /Gin Engine源码详解-LMLPHP

    而新的RouterGroup是通过Engine调用Group函数产生的;也就是我们自己的Group

    那么以后在这个Group注册的路径都会自动加上/user的路径。

    为什么会自动添加路径,后面还会分析相关细节。

    gin.methodTree 源码

    type node struct {
       path      string
       indices   string
       wildChild bool
       nType     nodeType
       priority  uint32
       children  []*node // child nodes, at most 1 :param style node at the end of the array
       handlers  HandlersChain
       fullPath  string
    }
    
    type methodTree struct {
        method string
        root   *node
    }
    
    type methodTrees []methodTree
    登录后复制

    对于node的添加和查找我就不展开讲了,如果不懂的可以自行搜索字典树和查看 httprouter 的实现。

    我们刚刚在gin.New 函数中可以看到,trees是一个methodTree的切片,并在在初始化给了默认容量为9是容量不是长度哦

    addRoute 函数中可以看到trees的添加:

    如果开始没有对应方法的根路径node对象,就会创建一个出来,然后再去添加对应的路由注册。

    整体的流程分析

    gin框架中,主要可以使用下面几种注册方式:

    这些注册在下面其实都是调用的同一个方法,我们接下来就要来翻开她的外衣看看里面是什么样的。Gin Engine源码详解-LMLPHP

    可以看到都是调用的group.handle 方法Gin Engine源码详解-LMLPHP

    我们来看一下这个方法都做了哪些事情:

    combineHandlers 支持最大的函数数量为63-1个Gin Engine源码详解-LMLPHP

    Group 函数

    现在来看Group的实现,通过调用这个方法会产生一个新的RouterGroup 并根据参数设置的基础路径,和全局engine实体,并把基础的中间件也复制到其中。

    使用分组路由最后也是调用group.handle方法进行注册,只是其中的basePath在分组的时候已经设置好了,加上注册函数时的路径,就是这个请求的路由路径。

    需要注意的一点,我之前想过使用·Group·后,它后面的注册没有使用返回值,注册的路由是怎么注册到全局路由表中的,看过源码才明白。

    添加路由的时候,是获取的全局engine 实体,所以也是添加到全局路由表中的。

    最后需要注意的

    在使用注册中间件和注册路由的时候,需要注意他们注册的顺序。

    上一点错误的注册方式代码:

    package main
    
    import (
     "github.com/gin-gonic/gin"
    )
    
    func main() {
     eng := gin.New()
     eng.POST("login", func(context *gin.Context) {
      // 处理登录信息
     })
     eng.Use(gin.Logger())
    
     userGroup := eng.Group("/user")
     userGroup.GET("info", func(context *gin.Context) {
      // 参数验证
    
      // 处理逻辑
     })
    
     adminGroup := eng.Group("/admin")
     adminGroup.GET("info", func(context *gin.Context) {
      // 参数验证
    
      // 处理逻辑
     })
    
     eng.Use(gin.Recovery())
     adminGroup.PUT("info", func(context *gin.Context) {
      // 参数验证
    
      // 处理逻辑
     })
     eng.GET("logout", func(context *gin.Context) {
      // 处理登录信息
     })
     eng.Run(":8080")
    }
    登录后复制

    运行结果:

    可以看到在注册路由之后,再注册中间件,那么前面注册过的路由是没有这个中间件的。

    以上就是Gin Engine源码详解的详细内容,更多请关注Work网其它相关文章!

    09-04 18:26