gin: 中间件的作用范围和执行顺序
一,常用的三个作用范围
1, 作用顺序:
实际中间件在工作时,按照注册顺序,路由前处理顺序为由前往后,后处理则由后往前
2,作用范围:
全局中间件: 该中间件以下的路由都可以生效
组路由中间件:对提定的路由组生效
单个路由中间件:对指定的单个路由生效
二,代码例子:
1,中间件代码:
package middleware
import (
"fmt"
"github.com/gin-gonic/gin"
"time"
)
//全局middlewareOne
func GlobalMiddlewareOne() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("==before GlobalMiddlewareOne: "+time.Now().String())
c.Next()
fmt.Println("==after GlobalMiddlewareOne: "+time.Now().String())
return
}
}
//全局middlewareTwo
func GlobalMiddlewareTwo() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("==before GlobalMiddlewareTwo: "+time.Now().String())
c.Next()
fmt.Println("==after GlobalMiddlewareTwo: "+time.Now().String())
return
}
}
//分组middlewareOne
func GroupMiddlewareOne() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("==before GroupMiddlewareOne: "+time.Now().String())
c.Next()
fmt.Println("==after GroupMiddlewareOne: "+time.Now().String())
return
}
}
//分组middlewareTwo
func GroupMiddlewareTwo() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("==before GroupMiddlewareTwo: "+time.Now().String())
c.Next()
fmt.Println("==after GroupMiddlewareTwo: "+time.Now().String())
return
}
}
//第一个单路由middleware
func MiddlewareOne() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("==before middlewareOne: "+time.Now().String())
c.Next()
fmt.Println("==after middlewareOne: "+time.Now().String())
return
}
}
//第二个单路由middleware
func MiddlewareTwo() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("==before middlewareTwo: "+time.Now().String())
c.Next()
fmt.Println("==after middlewareTwo: "+time.Now().String())
return
}
}
2,路由文件中启用中间件
routes/routes.go
package routes
import (
"bytes"
"fmt"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"runtime"
"imagebank/controller"
"imagebank/global"
"imagebank/middleware"
"runtime/debug"
)
func Routes() *gin.Engine {
router := gin.Default()
//处理找不到路由
router.NoRoute(HandleNotFound)
router.NoMethod(HandleNotFound)
//处理发生异常
router.Use(Recover)
//启用全局中间件
router.Use(middleware.GlobalMiddlewareTwo())
router.Use(middleware.GlobalMiddlewareOne())
//image
image := controller.NewImageController()
//组路由中间件的另一种格式: protected := r.Group("/protected", AuthMiddleware())
//启用组路由中间件
imageGroup := router.Group("/image").Use(middleware.AccessLog()).Use(middleware.GroupMiddlewareTwo(),middleware.GroupMiddlewareOne())
{
//启用单路由中间件
imageGroup.GET("/detail", middleware.MiddlewareTwo(),middleware.MiddlewareOne(),image.Detail)
imageGroup.GET("/list", image.List)
imageGroup.POST("/add", image.Add)
}
//访问根目录
router.GET("/", image.List)
//处理ico
router.GET("/favicon.ico", func(c *gin.Context) {
c.String(404, "not exist")
})
return router
}
三,测试效果
13:58:11 app | ==before GlobalMiddlewareTwo: 2025-02-12 13:58:11.952985281 +0800 CST m=+8.073509524
13:58:11 app | ==before GlobalMiddlewareOne: 2025-02-12 13:58:11.953424383 +0800 CST m=+8.073947749
13:58:11 app | ==before GroupMiddlewareTwo: 2025-02-12 13:58:11.95366456 +0800 CST m=+8.074188745
13:58:11 app | ==before GroupMiddlewareOne: 2025-02-12 13:58:11.95417904 +0800 CST m=+8.074702449
13:58:11 app | ==before middlewareTwo: 2025-02-12 13:58:11.983823789 +0800 CST m=+8.104348260
13:58:11 app | ==before middlewareOne: 2025-02-12 13:58:11.98415494 +0800 CST m=+8.104677950
13:58:11 app | ==after middlewareOne: 2025-02-12 13:58:11.984662163 +0800 CST m=+8.105185160
13:58:11 app | ==after middlewareTwo: 2025-02-12 13:58:11.985269393 +0800 CST m=+8.105811460
13:58:11 app | ==after GroupMiddlewareOne: 2025-02-12 13:58:11.986983707 +0800 CST m=+8.107508149
13:58:11 app | ==after GroupMiddlewareTwo: 2025-02-12 13:58:11.98743741 +0800 CST m=+8.107960423
==after GlobalMiddlewareOne: 2025-02-12 13:58:11.992469759 +0800 CST m=+8.112994679
==after GlobalMiddlewareTwo: 2025-02-12 13:58:11.992499402 +0800 CST m=+8.113040999
可以看到:
有多个middleware时
对于next之前的代码,是按use的顺序生效,
而next之后的代码,则是按相反的顺序生效
浙公网安备 33010602011771号