Gin中间件实现
Gin的中间件是一个洋葱模型,中心为最终处理请求的 handler,称为 main handler,其他为 middleware handler 。每一个 middleware handle 可以分为两部分,随着 request 的流动,左边是入,右边为出,而分割点就是 next,本质就是通过这个next来执行函数链 。
package main
import(
"fmt"
"math"
)
const abortIndex int8 = math.MaxInt8/2
type Context struct {
handlers []func(c *Context)
index int8
}
func (c *Context) Use(f func(c *Context)) {
c.handlers = append(c.handlers, f)
}
func (c *Context) GET(path string, f func(c *Context)) {
c.handlers = append(c.handlers, f)
}
func (c *Context) Next() {
if c.index < abortIndex {
c.index++
c.handlers[c.index](c) // 执行下一个中间件
}
}
func (c *Context) Abort() {
c.index = abortIndex
}
func (c *Context) Run() {
c.handlers[0](c) // 执行第一个中间件
}
func main() {
c := &Context{}
c.Use(Middleware1())
c.Use(Middleware2())
c.Use(Middleware3())
c.GET("/", func(c *Context){
fmt.Println("Get handle function!!!")
})
c.Run()
}
func Middleware1() func(c *Context) {
return func(c *Context) {
fmt.Println("middleware1-start")
c.Next()
fmt.Println("middleware1-end")
}
}
func Middleware2() func(c *Context) {
return func(c *Context) {
fmt.Println("middleware2-start")
c.Abort()
c.Next()
fmt.Println("middleware2-end")
}
}
func Middleware3() func(c *Context) {
return func(c *Context) {
fmt.Println("middleware3-start")
c.Next()
fmt.Println("middleware3-end")
}
}