微服务拦截器
类似web服务当中的中间件
实现思路
将最终执行函数与拦截器通过一个相同的invoker来进行包装,并且通过递归来实现。
代码实现
package main
import (
"context"
"fmt"
)
type interceptor func(ctx context.Context, ivk invoker)error
type invoker func(ctx context.Context, interceptors []interceptor) error
func main() {
var ctx context.Context
var ceps []interceptor
var inter1 = func(ctx context.Context, ivk invoker) error{
fmt.Println("interceptor.")
return ivk(ctx, ceps)
}
var inter2 = func(ctx context.Context, ivk invoker) error{
fmt.Println("interceptor.")
return ivk(ctx, ceps)
}
var ivk = func(ctx context.Context, interceptors []interceptor) error {
fmt.Println("invoker start")
return nil
}
ceps = append(ceps, inter1, inter2)
cepChain := getCepChain(ctx, ceps, ivk)
cepChain(ctx, ivk)
}
func getCepChain(ctx context.Context, interceptors []interceptor, ivk invoker) interceptor {
if len(interceptors) == 0 {
return nil
}
if len(interceptors) == 1 {
return interceptors[0]
}
return func(ctx context.Context, ivk invoker) error{
return interceptors[0](ctx, getInvoker(ctx, interceptors, 0, ivk))
}
}
func getInvoker(ctx context.Context, interceptors []interceptor, cur int, ivk invoker) invoker {
if cur == len(interceptors) - 1 {
return ivk
}
return func(ctx context.Context, interceptors []interceptor) error {
return interceptors[cur+1](ctx, getInvoker(ctx, interceptors, cur+1, ivk))
}
}
执行结果