首页 > 其他分享 >gin框架分析二:gin初始化,默认配置实例构建过程

gin框架分析二:gin初始化,默认配置实例构建过程

时间:2023-01-24 16:33:44浏览次数:50  
标签:engine 初始化 Use 默认 实例 gin 路由

gin的函数调用流程

gin的函数调用过程大概如下图:

GIN函数调用过程第一步构建GIN实例,第二步构建GIN路由,第三步则是启动http.server包,坚挺HTTP请求,并将请求处理交给gin框架,gin又通过路由匹配寻找到对应的handler去具体处理每一个请求。

GIN的初始化过程

我们会从上面函数调用图的方法顺序开始过源码,并尝试弄清楚gin在各个阶段都干了些什么内容。

得到默认配置的gin实例

main函数代码中通过 gin.Default() 函数可以获取到一个默认配置的engine实例,Default()函数如下:

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

debugPrintWARNINGDefault()函数首先被调用,其检测go版本是否在1.14+,如果不满足条件则给出一个警告,仅仅是一个警告而不做其他操作。

func debugPrintWARNINGDefault() {
	if v, e := getMinVer(runtime.Version()); e == nil && v <= ginSupportMinGoVer {
		debugPrint(`[WARNING] Now Gin requires Go 1.14+.

`)
	}
	debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

`)
}

通过调用New()函数,构造出一个默认配置项的engin实例。

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", "::/0"},
		trustedCIDRs:           defaultTrustedCIDRs,
	}
	engine.RouterGroup.engine = engine
	engine.pool.New = func() any {
		return engine.allocateContext()
	}
	return engine
}

 其中gin对于Context的处理使用了一个sync.Pool来处理,这样可以在每次对于Context的实例都不用重复生成,可以尽可能重复利用已经存在的实例。

engine.Use(Logger(), Recovery())方法默认为engine添加Logger和Recovery两个中间件,并保存于RouterGroup.Handlers中,然后在路由添加处理器是合并进各个路由处理中调用,这就是为什么通过gin.Default()生成实例后对于添加的路由处理方法会有3个handler的原因。

例如:

router.GET("/ping", func(c *gin.Context) {
		c.String(200, "pong %d", counter)
		counter = counter + 1
	}) 

如上路由处理对应的路由信息为:

进入engine.Use(Logger(), Recovery())方法:

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

其调用父类的Use方法把默认中间件添加到RouterGroup.Handlers,同时构建了404和405的异常处理钩子函数。

至此,gin.Defaults()创建了一个包含两个默认中间件、一个可重复利用Context并在Context实例不足时生成实例的gin engin,在获得默认配置的的gin实例后接下来的任务就是构建路由树和对应的处理方法。

 

标签:engine,初始化,Use,默认,实例,gin,路由
From: https://www.cnblogs.com/xmy20051643/p/17064132.html

相关文章

  • gin框架分析一:框架结构概览
    简介Gin是一个用Go(Golang)编写的web框架,其速度快,简单易学,结构简单。总体结构主要类图 gin框架核心为Engin类,其继承RouterGroup类并实现了GO标准库中的哦http.H......
  • 让程序只运行一个实例的简单实用的方法
    ////只能运行一个实例HANDLEhMutexOneInstantance=CreateMutex(NULL,TRUE,_T("PreventSecondInstance"));BOOLbFound=FALSE;if(GetLastError()==ERROR_ALREADY_EXISTS......
  • Let‘s begin!
    继https://www.youtube.com/watch?v=PtQiiknWUcI之后https://www.youtube.com/watch?v=c708Nf0cHrs这个课程更加符合我的要求Let‘sbegin!......
  • 安卓请求后端初始化列表数据
    :1、首先在安卓端实现一个接口,用来接收请求,获取列表数据:publicinterfaceGetListDataInterface{@GET("/listData")Call<List<String>>getListData();}......
  • Nginx与LUA(7)
    您好,我是湘王,这是我的51CTO博客。值此新春佳节,我给您拜年啦~祝您在新的一年中所求皆所愿,所行皆坦途,展宏“兔”,有钱“兔”,多喜乐,常安宁!软件开发中,除了进程和线程,还有协程的概......
  • 嵌入 WebAssembly 运行时和实例化 WebAssembly 模块的几大要素
    下面这段代码忽略了错误处理机制,介绍了如何在Go语言开发的宿主程序中嵌入WebAssembly.funccreateWasmVM(code[]byte){engine:=wasmtime.NewEngine()mod......
  • nginx添加身份认证
    前言有一些静态网站资源,我们不希望所有人都可以访问,那么可以简单使用nginx内置模块实现身份认证。实现修改配置文件:auth_basic"nginxbasichttptest";auth_basic_u......
  • Nginx与LUA(7)
    您好,我是湘王,这是我的博客园。值此新春佳节,我给您拜年啦~祝您在新的一年中所求皆所愿,所行皆坦途,展宏“兔”,有钱“兔”,多喜乐,常安宁!   软件开发中,除了进程和线程,还有......
  • nginx添加身份认证
    前言有一些静态网站资源,我们不希望所有人都可以访问,那么可以简单使用nginx内置模块实现身份认证。实现修改配置文件:auth_basic"nginxbasichttptest";auth_basic_us......
  • Verilog实例(二)交通信号灯控制器
    功能说明 状态图 状态信号S0Hwy=G,Cntry=RS1Hwy=Y,Cntry=RS2Hwy=R,Cntry=RS3Hwy=R,Cntry=GS4Hwy=R,Cntry=YVerilog代码 `......