自己根据go-zero单体框架实现的一个精简版框架https://github.com/wanmei002/go-zero-learn, 新手直接看go-zero 框架可能会绕,看这个好理解
中间件的添加
-
在 server.Server 结构体有个一方法 Use
// Use adds the given middleware in the Server. func (e *Server) Use(middleware Middleware) { e.ngin.use(middleware) } type Middleware func(next http.HandlerFunc) http.HandlerFunc func (s *engine) use(middleware Middleware) { s.middlewares = append(s.middlewares, middleware) }
-
最后 中间件(Middleware) 都添加到了 Server.ngin.middleware 属性里
中间件的原理
详细讲解请看我的另一篇文章https://blog.csdn.net/wanmei002/article/details/106174126
-
结构:
type Middleware func(next http.HandlerFunc) http.HandlerFunc
-
http.HandlerFunc 结构
type HandlerFunc func(ResponseWriter, *Request) // ServeHTTP calls f(w, r). func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { f(w, r) }
http.HandlerFunc 类型有一个方法 ServeHTTP, 这个方法就是执行自己本身
-
我们处理路由的函数就是 HandlerFunc 类型的,中间件也是 HandlerFunc 类型的,此时我们把处理路由的函数当做参数传进去 Middleware类型的方法里,然后处理做一些逻辑,
把这些逻辑和传进来的HandlerFunc 在封装成一个 HandlerFunc 的类型返回出去,依此类推,像递归一样一层一层的封装
亲手实现一个中间件
func ConsumeTime(next http.HandlerFunc) http.HandlerFunc {
return func (w http.ResponseWriter, r *http.Request) {
nowTime := time.Now()
next.ServeHTTP(w, r)// 运行传进来的中间件
sub := time.Now().Sub(nowTime).Nanoseconds()/1e6
fmt.Printf("处理请求耗费 [%v] 毫秒\n", sub)
}
}