GIn源码学习

Gin源码学习

Gin工作流程
1、gin.Default
2、r.GET
3、r.Run
初始化实例 engine := New()
注册中间件 engine.Use()
处理注册路由 group.handle
构造路由树 group.engine.addRoute
调用net-http模块
实现serverHttp

gin.Default 源码

func Default() *Engine {
	debugPrintWARNINGDefault()
	engine := New()
	engine.Use(Logger(), Recovery())
	return engine
}
  • Engine

    • Engine是一个struct,包含了路由,中间件,配置等相关信息
      • trees包含了路由和处理方法的映射,用的是类似字典树的结构
      • pool 用了sync.Pool类型,来减少频繁context实例化带来的资源消耗
      • RouterGroup 其中的Handlers存储了中间件的信息
  • New方法

    • 初始化了Engine

    • 将RouterGroup的Handlers(数组)设置成nil, basePath设置成 /

    • 刚刚初始化的Engine也被赋值给了RouterGroup的engine

      func New() *Engine {
      	debugPrintWARNINGNew()
      	engine := &Engine{
      		RouterGroup: RouterGroup{
      			Handlers: nil,
      			basePath: "/",
      			root:     true,
      		},
      		FuncMap:                template.FuncMap{},
      		RedirectTrailingSlash:  true,
      		RedirectFixedPath:      false,
      		HandleMethodNotAllowed: false,
      		ForwardedByClientIP:    true,
      		RemoteIPHeaders:        []string{"X-Forwarded-For", "X-Real-IP"},
      		TrustedPlatform:        defaultPlatform,
      		UseRawPath:             false,
      		RemoveExtraSlash:       false,
      		UnescapePathValues:     true,
      		MaxMultipartMemory:     defaultMultipartMemory,
      		trees:                  make(methodTrees, 0, 9),
      		delims:                 render.Delims{Left: "{{", Right: "}}"},
      		secureJSONPrefix:       "while(1);",
      		trustedProxies:         []string{"0.0.0.0/0"},
      		trustedCIDRs:           defaultTrustedCIDRs,
      	}
      	engine.RouterGroup.engine = engine
      	engine.pool.New = func() interface{} {
      		return engine.allocateContext()
      	}
      	return engine
      }
      
  • 跟New相比,Default就是默认多调用了Logger(), Recovery()

  • Use方法

    1. use方法就是调用RouterGroup.Use()RouterGroup.Handlers写入记录

    2. Handlers就是一个数组,用来存储中间件信息

    3. 注册路由的时候会用RouterGrouphandle方法把路由对应的函数和之前的中间件一起放到handlers里

      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()
      }
      
      1. handle方法用combineHandlers方法来把路由的中间件函数和处理函数结合到一起得到一个由HandlerFunc组成的切片

      2. HandlerFunc 是一个*Context类型的函数

        type HandlersChain []HandlerFunc
        
        type HandlerFunc func(*Context)
        
  • 中间件的执行

    • Next方法遍历HandlersChain来执行中间件
    • 中间件之间传输数据用了c.Set()c.Get(),比如我们可以在认证中间件中获取当前请求的相关信息(userID等)通过c.Set()存入c,然后在后续处理业务逻辑的函数中通过c.Get()来获取当前请求的用户。c就像是一根绳子,将该次请求相关的所有的函数都串起来了。

路由

路由注册过程

  1. 第一次注册路由,例如注册a

  2. 继续注册一条没有公共前缀的路由,例如bc

  3. 注册一条与先前注册的路由有公共前缀的路由,例如bd

注册路由
路由a
公共部分b
路由c
路由d

Run

  • 通过调用 net/http 来启动服务,由于 engine 实现了 ServeHTTP 方法

  • 只需要直接传 engine 对象就可以完成初始化并启动

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值