go web框架 gin-gonic源码解读01————Engine

这篇具有很好参考价值的文章主要介绍了go web框架 gin-gonic源码解读01————Engine。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

go web框架 gin-gonic源码解读01————Engine


gin-gonic是go语言开发的轻量级web框架,性能优异,代码简洁,功能强大。有很多值得学习的地方,最近准备把这段时间学习gin的知识点,通过engine,context,router,middleware几篇博客文章总结总结。

而Engine是gin框架最核心的结构体。
// Engine is the framework's instance, it contains the muxer, middleware and configuration settings.
// Create an instance of Engine, by using New() or Default()
type Engine struct {
// ... 略
}

为什么gin需要设计一个Engine结构体?
因为gin框架依赖于go本身的 net/http 包来提供http服务。 net/http 包的http服务可以用以下方式快速的启动:

type mHandle struct {
}

func (i mHandle ) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	w.Write([]byte("Hello"))
}

func HttpRun() {
	// mHandle{} 实现了 net/http中的Handler接口
	http.Handle("/", mHandle{})
	http.ListenAndServe(":9999", nil)
}
// net/http中的Handler接口
// type Handler interface {
//	 ServeHTTP(ResponseWriter, *Request)
// }

而我们gin框架的Engine也实现了一个net/http包的Handler接口。当是gin既然是依赖老的net/http为什么大家不直接使用net/http,而是需要使用gin呢,那是因为net/http在大多数情况下只支持静态路由,而且不能很好的支持动态路由,对中间件的开发也不友好,也不能很好的支持http模版的返回,所以大多数时候我们更倾向于使用集成了这些功能的gin,并且gin的代码量很少,简直是小而美。文章来源地址https://www.toymoban.com/news/detail-620523.html

type Engine struct {
	// ... 略

	// 对象池,这里用于存放gin.Context对象,减少内存分配,降低 GC 压力。
	pool	sync.Pool
	// 路由树
	trees  methodTrees
}

// ServeHTTP conforms to the http.Handler interface.
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	// Context是gin框架为了更方便的处理http的请求与响应,(即w http.ResponseWriter, req *http.Request)
	// 而对进行的封装,每次接受到http请求都需要封装一下Context结构体,交由下一步代码执行,Context在后续的博客中会有详细的介绍
	c := engine.pool.Get().(*Context)
	c.writermem.reset(w)
	c.Request = req
	c.reset()

	// 将请求交于逻辑函数执行
	engine.handleHTTPRequest(c)

	// 执行完了进行归还
	engine.pool.Put(c)
}

// 逻辑函数,这里来解析请求的url,然后路由匹配该路径需要执行的方法
func (engine *Engine) handleHTTPRequest(c *Context) {
	// 获取请求方法GET,POST..
	httpMethod := c.Request.Method
	// 获取url
	rPath := c.Request.URL.Path
	unescape := false
	// 如果地址存在原始地址,则使用原始地址
	if engine.UseRawPath && len(c.Request.URL.RawPath) > 0 {
		rPath = c.Request.URL.RawPath
		unescape = engine.UnescapePathValues
	}

	if engine.RemoveExtraSlash {
		// cleaenpPath 函数作用类似于filepath.Clean(),是为了获取最短有效url
		rPath = cleanPath(rPath)
	}

	// Find root of the tree for the given HTTP method
	// engine.trees中存放是gin框架的路由树,它采用前缀树结构来搞笑的存储各类路由	
	// 后续的博客会对路由树有更为详细的介绍,这里就简单介绍一下。
	t := engine.trees
	for i, tl := 0, len(t); i < tl; i++ {
		// 路由树的第一层孩子节点都是请求方法,如GET,POST。。。
		if t[i].method != httpMethod {
			continue
		}
		root := t[i].root
		// Find route in tree
		// 查找请求的url是否有对应的url路由配置
		value := root.getValue(rPath, c.params, c.skippedNodes, unescape)
		if value.params != nil {
			c.Params = *value.params
		}
		// value.handlers存储的就是该路由的逻辑处理方法
		if value.handlers != nil {
			c.handlers = value.handlers
			c.fullPath = value.fullPath
			// c.Next是gin框架调用handlers与各类中间件的一种便捷的方式,后续讲中间件的时候会重点介绍。
			c.Next()
			// 处理完了,写入响应的头文件
			c.writermem.WriteHeaderNow()
			return
		}

		// 执行到这里了说明value.handlers == nil,这里判断是不是重定向请求,然后进行重定向处理
		if httpMethod != http.MethodConnect && rPath != "/" {
			if value.tsr && engine.RedirectTrailingSlash {
				redirectTrailingSlash(c)
				return
			}
	
			// 实在找不到,就尝试修复你的url看看能不能找到合适的路由来处理
			if engine.RedirectFixedPath && redirectFixedPath(c, root, engine.RedirectFixedPath) {
				return
			}
		}
		break
	}

	// HandleMethodNotAllowed 这个配置如果开启,并且没有找到合适的路由来处理该请求,就会尝试别的method 会不会有可以解析该请求的路由
	if engine.HandleMethodNotAllowed {
		for _, tree := range engine.trees {
			// 相同method的上面已经找过了,这里continue
			if tree.method == httpMethod {
				continue
			}
			// 到别的请求方法下面嚯嚯
			if value := tree.root.getValue(rPath, nil, c.skippedNodes, unescape); value.handlers != nil {
				c.handlers = engine.allNoMethod
				serveError(c, http.StatusMethodNotAllowed, default405Body)
				return
			}
		}
	}
	// 啥招都没有了,调用统一的失败处理函数,响应该请求
	c.handlers = engine.allNoRoute
	serveError(c, http.StatusNotFound, default404Body)
}

到了这里,关于go web框架 gin-gonic源码解读01————Engine的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Go语言Web框架Gin常见用法

    Gin是目前Go语言最为常用的Web框架,日常工作中也少不了使用此框架,编写此使用总结文档以备后用。 此文档参考官方文档编写,仅用于自我学习总结和参考。 我一直认为编写文档的意义一方面是给其他人提供了些许帮助,另一方面则是让自己加深了对知识的理解并为自己提

    2024年02月03日
    浏览(35)
  • 基于go语言gin框架的web项目骨架

    节省时间与精力,更高效地打造稳定可靠的Web项目:基于Go语言和Gin框架的完善Web项目骨架。无需从零开始,直接利用这个骨架,快速搭建一个功能齐全、性能优异的Web应用。充分发挥Go语言和Gin框架的优势,轻松处理高并发、大流量的请求。构建可扩展性强、易于维护的代码

    2024年02月08日
    浏览(32)
  • 初始化一个Gin框架的Go-Web项目

    使用到的第三方库 gin Gin 框架 viper 配置文件管理 cors 跨域资源请求配置 gorm ORM 库 zap 日志记录 Go 语言程序的入口点 main.go 文件 使用 flag 读取配置文件路径参数,默认当前目录下 使用 viper 读取 config.ini 配置文件初始化初始数据 初始化随机数种子 初始化数据库 声明启动程序

    2024年02月09日
    浏览(40)
  • 【Go Web开发】Web初识、RESTful架构和RESTful API详解、Gin框架的安装和简单使用

    博主简介: 努力学习的大一在校计算机专业学生,热爱学习和创作。目前在学习和分享:数据结构、Go,Java等相关知识。 博主主页: @是瑶瑶子啦 所属专栏: Go语言核心编程 近期目标: 写好专栏的每一篇文章 全称: “万维网”(World Wide Web) 本质: 系统(基于互联网).

    2024年02月03日
    浏览(39)
  • Go(四)gin框架

    1.1、下载和安装gin 下载包:go get github.com/gin-gonic/gin 使用go mod管理包: 1)初始化 Go Modules :go mod init your_module_name,这将创建一个 go.mod 文件,记录你的项目的模块信息和当前依赖关系; 2)复制依赖包到vendor目录 :\\\"go mod vendor\\\" 会将项目的所有包复制到vendor目录中。这包括

    2024年01月25日
    浏览(27)
  • Go-Gin框架

    Gin是一个用Go编写的HTTPweb框架。它是一个类似于martini但拥有更好性能的API框架, 优于httprouter,速度提高了近 40 倍。 点击此处访问Gin官方中文文档。 新建文件main.go,内容如下: 运行后访问: http://localhost:8000/ Gin支持加载HTML模板, 然后根据模板参数进行配置并返回相应的数

    2024年02月20日
    浏览(30)
  • Go -【gin】框架搭建基本使用

    Gin是一个快速的Golang web框架,它使用了httprouter来处理路由和速度,而不是使用内置的Go路由。以下是Gin框架的搭建和使用: 这将从Gin GitHub仓库中安装最新版本的Gin框架。 在搭建一个Gin应用程序之前,让我们了解一下Gin的基本架构: Router :它是Gin应用程序的核心部分,它接

    2024年02月16日
    浏览(28)
  • GO学习之 微框架(Gin)

    1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Http) 11、GO学习之 微框架(Gin) 12、GO学习

    2024年02月13日
    浏览(29)
  • go语言Gin框架常见面试题(1)

    Gin框架是一种基于Go语言的轻量级Web框架,具有高效、快速、易用等优点。Gin采用了类似于Expres

    2024年02月08日
    浏览(52)
  • Go新项目-为何选Gin框架?(0)

    先说结论:我们选型Gin框架 早在大概在2019年下旬,由于内部一个多线程上传的需求,考虑到Go协程的优势; 内部采用Gin框架编写了内部的数据上传平台BAP,采用Gin+Vue开发,但前期没考虑到工程化思维,导致代码后期维护程度变得很复杂,硬编码内容过多,重复内容过多;

    2024年01月17日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包