Golang中可以通过定义一个函数类型,并且在函数类型上定义方法,满足该函数类型签名的函数可以转换为该函数类型,并且调用函数类型实现的方法,有些框架的中间件就是通过这种方式实现的,比如下面这段代码:
package main
import (
"context"
"fmt"
)
type HandlerFunc func(*context.Context)
func (f HandlerFunc) Work(ctx *context.Context) {
f(ctx)
}
func Outer(next HandlerFunc) {
ctx := context.WithValue(context.Background(), "key1", "value1")
next.Work(&ctx)
}
func Inner(ctx *context.Context) {
logstr := fmt.Sprintf("i am inner, the value is: %s", (*ctx).Value("key1"))
fmt.Println(logstr)
}
func main() {
inner := HandlerFunc(Inner)
Outer(inner)
}
复制代码
Inner是实际的业务处理函数,Outer实现为中间件接收HandlerFunc类型的函数作为参数,然后在中间件逻辑之后,调用next.Work()处理业务逻辑。
直接将函数作为参数传递也能实现中间件的原理,比如:
package main
import (
"context"
"fmt"
)
func Outer(next func(*context.Context)) {
ctx := context.WithValue(context.Background(), "key1", "value1")
next(&ctx)
}
func Inner(ctx *context.Context) {
logstr := fmt.Sprintf("i am inner, the value is: %s", (*ctx).Value("key1"))
fmt.Println(logstr)
}
func main() {
Outer(Inner)
}
复制代码