面向切面开发,类比python的装饰器

全局中间件

所有请求都经过此中间件

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/gin-goinc/gin"
  6. )
  7. // define middleware
  8. func Middleware() gin.HandlerFunc {
  9. return func(c *gin.Context) {
  10. t := time.Now()
  11. fmt.Println("middleware start")
  12. // set variable into Context
  13. c.Set("foo", "bar")
  14. status := c.Writer.Status()
  15. fmt.Println("middleware finish", status)
  16. t2 := time.Since(t)
  17. fmt.Println("time:", t2)
  18. }
  19. }
  20. func main() {
  21. r := gin.Default()
  22. r.Use(Middleware())
  23. {
  24. r.GET("/test", func(c *gin.Context) {
  25. // get variable
  26. req, _ := c.Get("foo")
  27. fmt.Println("foo", req)
  28. c.JSON(200, gin.H{"foo": req})
  29. })
  30. }
  31. r.Run()
  32. }

输出

  1. middleware start
  2. middleware finish
  3. time: 0 s
  4. foo: bar

代码中计算时间差没有执行?(我感觉是执行了,先把中间件里面的都走完,再走具体的函数)

Next()方法

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/gin-goinc/gin"
  6. )
  7. // define midlleware
  8. func MiddleWare() gin.HandlerFunc {
  9. return func(c *gin.Context) {
  10. t := time.Now()
  11. fmt.Println("middleware start")
  12. // set variable
  13. c.Set("foo", "bar")
  14. // execute function
  15. c.Next()
  16. // something execute after function
  17. status := c.Writer.Status()
  18. fmt.Println("middleware finsih", status)
  19. t2 := time.Since(t)
  20. fmt.Println("time:", t2)
  21. }
  22. }
  23. func main() {
  24. r := gin.Default()
  25. r.Use(MiddleWare())
  26. {
  27. r.GET("/test", func(c *gin.Context) {
  28. req, _ := c.Get("foo")
  29. fmt.Println("foo:", req)
  30. c.JSON(200, gin.H{"foo:": req})
  31. })
  32. }
  33. r.Run()
  34. }

输出

  1. middleware start
  2. foo: bar
  3. middleware finish
  4. time: 998.6 μs

走到先走中间件的前几句,遇到Next()转而去执行具体的函数,执行完回来继续执行剩余的中间件代码,类似 中断操作?

局部中间件

与全局中间不同的地方在于使用方式,定义是一样的

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. "github.com/gin-gonic/gin"
  6. )
  7. // define middleware
  8. func MiddleWare() gin.HandlerFunc {
  9. return func(c *gin.Context) {
  10. t := time.Now()
  11. fmt.Println("middleware start")
  12. c.Set("foo", "bar")
  13. c.Next()
  14. status := c.Writer.Status()
  15. fmt.Println("middleware finsih", status)
  16. t2 := time.Since(t)
  17. fmt.Println("time:", t2)
  18. }
  19. }
  20. func main() {
  21. r := gin.Default()
  22. // 中间件在局部使用
  23. r.GET("/text", Middleware(), func(c *gin.Context) {
  24. req, _ := c.Get("foo")
  25. fmt.Println("foo:", req)
  26. c.JSON(200, gin.H{"foo": bar})
  27. })
  28. r.Run()
  29. }