• gin 中间件


    中间件格式

    gin.HandlerFunc,满足这个函数即可

    //gin.HandlerFunc
    type HandlerFunc func(*Context)
    
    • 1
    • 2

    使用

    通过 engine.Use(gin.HandlerFunc) 注册

    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    	"time"
    )
    
    func log() gin.HandlerFunc {
    	return func(c *gin.Context) {
    		now := time.Now()
           //执行下一个中间件 
    		c.Next()
    		end := time.Since(now)
    		fmt.Printf("请求耗时 %s", end)
    	}
    }
    
    func main() {
    	r := gin.New()
    	r.Use(log())
    	r.GET("/ping", func(c *gin.Context) {
    		c.JSON(http.StatusOK, gin.H{
    			"message": "pong",
    		})
    	})
    	r.Run(":8080")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    终止中间件

    一般中间件的实现有两种模式:
    1.基于责任链的中间件,在中间件中return就不会执行下一个中间件
    2.基于AOP切面的中间件,return 不一定就不会执行下一个中间件

    gin的中间件就是基于AOP打造的。其中return还是会执行下一个中间件的,如果不想执行,需要调用gin.Context.Abort()方法

    package main
    
    import (
    	"fmt"
    	"github.com/gin-gonic/gin"
    	"net/http"
    	"time"
    )
    
    func log() gin.HandlerFunc {
    	return func(c *gin.Context) {
    		now := time.Now()
    		//想要终止中间件的执行,return 是无效的
    		c.Abort()
    		end := time.Since(now)
    		fmt.Printf("请求耗时 %s", end)
    	}
    }
    
    func main() {
    	r := gin.New()
    	r.Use(log())
    	r.GET("/ping", func(c *gin.Context) {
    		c.JSON(http.StatusOK, gin.H{
    			"message": "pong",
    		})
    	})
    	r.Run(":8080")
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    return 不能终止的原因

    //查看Next()方法源码
    func (c *Context) Next() {
    	c.index++
    	for c.index < int8(len(c.handlers)) {
    		c.handlers[c.index](c)
    		c.index++
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    c.handlers 中是中间件的执行函数,c.index 决定应该执行那个中间件了。
    假设现在c.haandlers中有A,B,C,D四个中间件。最开始gin会调用Next(),
    执行顺序A,B,C,D。其中A终止了并不会阻碍B,C,D的执行。如果中间件中不使用
    Next(),这时候他们是平行的。当A中调用了Next(),A中就嵌套了B,C,D中间件的执行。Abort() 将c.index 调整到一个远远大于len(c.handlers)的值,来阻止后续中间件的执行。

  • 相关阅读:
    Shaderlab的组成部分SubShader
    “微信小程序登录与用户信息获取详解“
    如果面试时,问你职业规划怎么答?
    Functional Programming in Java venkat(12) Working with Resources
    vue学习-12路由组件的基本使用
    Go — 相关依赖对应的exe
    ChatGPT从⼊⻔到精通
    SLAM从入门到精通(矩阵的使用)
    浮点数二分查找的实现
    Hadoop系列——大数据概念day1-1
  • 原文地址:https://blog.csdn.net/qq_29744347/article/details/125994941