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之后的代码,则是按相反的顺序生效

posted @ 2025-02-12 15:01  刘宏缔的架构森林  阅读(202)  评论(0)    收藏  举报