一个app网站,如皋网站建设公司,win10优化工具,全网营销概念概要 
目录 
Gin路由详解 
Gin框架路由之Radix Tree 
一、路由树节点 
二、请求方法树 
三、路由注册以及匹配 
中间件含义 
Gin框架中的中间件 主要讲述Gin框架路由和中间件的详细解释。本文章将从Radix树#xff08;基数树或者压缩前缀树#xff09;、请求处理、路由方法树…概要 
目录 
Gin路由详解 
Gin框架路由之Radix Tree 
一、路由树节点 
二、请求方法树 
三、路由注册以及匹配 
中间件含义 
Gin框架中的中间件 主要讲述Gin框架路由和中间件的详细解释。本文章将从Radix树基数树或者压缩前缀树、请求处理、路由方法树、路由的注册与匹配以及中间件的详细解释这五大部分入手。 Gin 框架 路由使用前缀树路由注册的过程就是构造前缀树的过程路由匹配的过程是查找前缀树 的过程。 
Gin路由详解 
Gin框架使用的是定制版本的httprouter。我们简单介绍下关于httprouer框架。 
Httprouter是一个高性能路由分发器它负责将不同方法的多个路径分别注册到各个handle函数。当收到请求时Httprouter会快速查找请求的路径是否有相对应的处理函数并执行相应的业务逻辑处理。 
Httprouter使用基数树radix tree来进行高效的路径查找这种数据结构适用于需要快速查找和匹配的场景。此外Httprouter还支持两种通配符匹配使得路由规则更加灵活和强大。 
它为Gin提供了高效、灵活的路由匹配功能使得Gin成为了一个高性能的Web框架。同时Httprouter也是Go语言中广泛使用的一个路由库独立于Gin框架可以被其他Go语言的Web框架所使用。 
Gin框架路由之Radix Tree 
Radix Tree 是一种更节省空间的前缀树。对于基数树的每个节点如果该节点是唯一的子树的话就和父节点合并。 
Radix Tree 可以被认为是一个简洁版的前缀树。我们注册路由的过程就是在构造前缀树的过程具有公共前缀的节点也共享一个公共父节点。 
如下图所示GET方法对应的路由树。 Priority优先级每个树级别上的子节点都按照优先级排序其中优先级就是在子节点上注册的句柄数量。优点优先匹配被大多数路由路径包含的节点更快速定位、最长路径可以优先匹配成本补偿。Handle: Get每个路由对应的实现函数。*数字 表示Handle处理函数的内存地址。 
URL具有层级结构并且都是有限的字符组所以有很多常见的前缀。这样是的我们很容易将路由简化为更小的问题。 
路由器为每种请求方法管理一颗单独的树。 
一、路由树节点 
type node struct {// 节点路径比如上面的search和upportpath      string// 和children字段对应, 保存的是分裂的分支的第一个字符// 例如search和support, 那么s节点的indices对应的eu// 代表有两个分支, 分支的首字母分别是e和uindices   string// 儿子节点children  []*node// 处理函数链条切片handlers  HandlersChain// 优先级子节点、子子节点等注册的handler数量priority  uint32// 节点类型包括static, root, param, catchAll// static: 静态节点默认比如上面的search等节点// root: 树的根节点// catchAll: 有*匹配的节点// param: 参数节点nType     nodeType// 路径上最大参数个数maxParams uint8// 节点是否是参数节点比如上面的:postwildChild bool// 完整路径fullPath  string
} 
二、请求方法树 每一个HTTP method都对应一颗radix树我们注册路由的时候都会调用addRoute函数。函数含义我们可以看到在注册路由的时候都是先根据请求方法获取对应的树也就是gin框架会为每一个请求方法创建一颗对应的树。只不过需要注意一个细节是gin框架中请求方法对应树关系并不是使用map而是使用的切片engine.trees的类型是methodThrees。 
type methodTree struct {method stringroot   *node
}type methodTrees []methodTree  // slicefunc (engine *Engine) addRoute(method, path string, handlers HandlersChain) {// liwenzhou.com...// 获取请求方法对应的树root : engine.trees.get(method)if root  nil {// 如果没有就创建一个root  new(node)root.fullPath  /engine.trees  append(engine.trees, methodTree{method: method, root: root})}root.addRoute(path, handlers)
} 
考点 为什么用切片存储请求方法树而不用map 节省内存。HTTP请求方法数量也就9种用切片存储和查询效率足够。只需要做出一次性内存申请即可。 
三、路由注册以及匹配 路由注册函数 
addRoute函数将具有给定句柄的节点添加到路径中。不是并发安全的函数。insertChild函数根据path本身进行分割将/分开的部分分别作为节点保存形成一颗树结构。参数匹配中的  和 *  的区别是前者是匹配一个字段后者是匹配后面所有的路径。 路由匹配 func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {// 这里使用了对象池c : engine.pool.Get().(*Context)// 这里有一个细节就是Get对象后做初始化c.writermem.reset(w)c.Request  reqc.reset()engine.handleHTTPRequest(c)  // 我们要找的处理HTTP请求的函数engine.pool.Put(c)  // 处理完请求后将对象放回池子
}func (engine *Engine) handleHTTPRequest(c *Context) {// 根据请求方法找到对应的路由树t : engine.treesfor i, tl : 0, len(t); i  tl; i {if t[i].method ! httpMethod {continue}root : t[i].root// 在路由树中根据path查找value : root.getValue(rPath, c.Params, unescape)if value.handlers ! nil {c.handlers  value.handlersc.Params  value.paramsc.fullPath  value.fullPathc.Next()  // 执行函数链条c.writermem.WriteHeaderNow()return}c.handlers  engine.allNoRouteserveError(c, http.StatusNotFound, default404Body)
}路由匹配是由节点的GetValue方法实现的。getValue根据给定的路径返回nodeValue值里面保存的处理函数和匹配到的路径参数数据。如果找不到任何处理函数会尝试TSR尾随斜杠重定向。  
中间件含义 中间件是指处理HTTP请求的函数或组件通常用于在请求到达目标处理程序之前或之后执行一些处理逻辑。中间件在Go语言中经常被使用因为它提供了一种可扩展和可重用的机制用于处理身份验证、授权、日志记录、错误处理等常见的Web应用程序需求。 中间件在Go语言主要是因为它提供了一种灵活、可扩展和可重用的机制用于处理Web应用程序中的各种需求和逻辑。 中间件优势 
函数式编程思想Go语言支持函数式编程风格而中间件提供了一种将函数作为参数传递并在请求处理过程中进行组合和调用的机制。使得代码更加模块化和可重用性。请求处理流程的可扩展性中间件允许开发人员将请求处理流程分解为多个独立的函数或组件这些 组件可以按照特定的顺序组合和调用。这种可扩展性使得开发人员可以轻松的添加、移除或替换中间件以满足特定的应用程序需求。前后置处理逻辑中间件可以在请求到达目标处理程序之前或之前执行一些处理逻辑例如身份验证、日志记录、错误处理等。这种机制使得开发人员可以轻松的请求处理过程中添加前后置处理逻辑而无需修改现有的代码。社区支持和普及。 
Gin框架中的中间件 gin框架中涉及中间件相关有4个常用的方法c.Next() 、c.Abort() 、c.Set()、c.Get() Gin中间件函数和处理函数是以切片的形式调用链条存在的我们可以顺序调用也可以借助c.Next函数方法实现嵌套调用。 c.Set()和c.Get()这两个方法多用于在多个函数之间通过c传递数据的比如我们可以在认证中间件中获取当前请求的相关信息userID等通过c.Set()存入c然后在后续处理业务逻辑的函数中通过c.Get()来获取当前请求的用户。c就像是一根绳子将该次请求相关的所有的函数都串起来了。 c.Abort()中断整个调用链条从当前函数返回。