中间件设计
Next()
常用于中间链中,把控制权传递给下一个中间件。 实现预处理和后处理
func Middleware1(next func()) {
fmt.Println("Before Middleware 1")
next()
fmt.Println("After Middleware 1")
}
func Middleware2(next func()) {
fmt.Println("Before Middleware 2")
next()
fmt.Println("After Middleware 2")
}
func FinalHandler() {
fmt.Println("Final Handler")
}
func main() {
// 构建中间件链
middlewareChain := Middleware1(Middleware2(FinalHandler))
// 执行中间件链
middlewareChain()
}
输出的结果如下:
Before Middleware 1
Before Middleware 2
Final Handler
After Middleware 2
After Middleware 1
自动处理
用户不主动调用下一个函数时的处理
示例如下:
fun(ctx *RequsestContext) Next(){
ctx.index++
for ctx.index < int8(len(ctx.handlers)){
ctx.handlers[ctx.index]()
ctx.index++
}
}
解释如下
这段代码看起来是一个中间件处理函数中的部分代码,用于实现中间件链中的控制流程。让我们逐步解释它:
fun(ctx *RequestContext) Next():这是一个函数定义,接收一个名为ctx的指向RequestContext结构体的指针作为参数。Next()是函数名,表明这是一个用于控制中间件链流程的函数。ctx.index++:ctx应该是一个保存中间件链状态的结构体,index可能是其中的一个字段,用于跟踪当前处理到了中间件链中的第几个中间件。for ctx.index < int8(len(ctx.handlers)):这是一个循环条件,表示当ctx.index小于中间件链中中间件的数量时,继续循环执行下面的代码。ctx.handlers[ctx.index]():这一行代码执行当前索引所指向的中间件函数。ctx.handlers应该是一个保存中间件函数的切片,ctx.index作为索引指示当前要执行的中间件函数。ctx.index++:在执行完当前中间件函数后,ctx.index递增,准备执行下一个中间件。- 整个循环会重复执行,直到
ctx.index超过中间件切片的长度,也就是所有中间件都被执行完毕。
异常处理
示例如下:
func (ctx *RequsestCOntext) Abort(){
ctx.index = IndexMax
}
ctx.Abort()是RequestContext结构体的一个方法。Abort()的目的是将ctx.index设置为一个特殊的值IndexMax,以表示请求处理过程中的中间件链应该立即中止,不再继续执行后续中间件。IndexMax可能是一个在代码中预定义的常量或枚举值,用于表示一个不可能达到的索引值。通常,IndexMax的值会设置得非常大,确保它超出了中间件切片的有效索引范围。- 当
ctx.index的值被设置为IndexMax后,for循环中的条件ctx.index < int8(len(ctx.handlers))将不再成立,即循环条件不满足,从而导致中间件链的执行被中止。
Gin中使用
Gin是一种用于构建Web应用程序的Golang(Go语言)框架,它也具有中间件的功能。
package main
import (
"github.com/gin-gonic/gin"
)
//中间件1
func LoggerMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 在请求到达处理程序之前记录或处理请求的逻辑
println("Logging request before handling...")
c.Next() // 继续到下一个处理程序
}
}
//中间件2
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 认证授权的逻辑
println("Authentication middleware...")
c.Next() // 继续到下一个处理程序
}
}
func main() {
//分配默认的路由
router := gin.Default()
// 添加中间件到“过滤器链”
// 按照添加顺序执行中间件
router.Use(LoggerMiddleware())
router.Use(AuthMiddleware())
router.GET("/hello", func(c *gin.Context) {
c.String(200, "Hello, Gin!")
})
router.Run(":8080")
}
/**
Logging request before handling...
Authentication middleware...
*/