@aliasliyu4
2018-09-28T16:53:13.000000Z
字数 3226
阅读 1323
type MyHandler interface {
ServeHTTP(w http.ResponserWriter, r *http.Request, next http.HandlerFunc)
}
next是下一个需要执行的http Handler,它作为一个参数被传递进去。
type MyHandlerFunc func (w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func (h MyHandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
h(w, r, next) // 调用ServeHTTP就是执行具体的MyHandlerFunc, 需要手动执行next函数
}
type middleware struct {
handler MyHandler // 当前Handler
next middleware // 下一个需要执行的middleware
}
// 实现ServeHTTP方法,也就是实现了http Handler.
func (m *middlerware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// m.next.ServeHTTP 自己调用自己,可以理解成进入下一个middleware
m.handler.ServeHTTP(w, r, m.next.ServeHTTP)
}
如上,midllerware就是一个Handler, 可在mux中注册,我们举个例子:
package main
import (
"fmt"
"net/http"
)
type MyHandler interface {
ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
}
type MyHandlerFunc func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
func (h MyHandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
h(w, r, next) // 调用ServerHTTP就是执行具体的MyHandlerFunc, 需要手动执行next函数
}
type middleware struct {
handler MyHandler // 当前Handler
next *middleware // 下一个需要执行的middleware
}
// 实现ServeHTTP方法,也就是实现了http Handler.
func (m middleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// m.next.ServeHTTP 自己调用自己,可以理解成进入下一个middleware
m.handler.ServeHTTP(w, r, m.next.ServeHTTP)
}
func build(myHandlers []MyHandler) middleware {
var next middleware
if len(myHandlers) == 0 {
return voidMiddleware()
} else if len(myHandlers) > 1 {
next = build(myHandlers[1:])
} else {
next = voidMiddleware()
}
return middleware{myHandlers[0], &next}
}
func voidMiddleware() middleware {
return middleware{
MyHandlerFunc(func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {}),
&middleware{},
}
}
var myHandlerOne = MyHandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
fmt.Println("use myHandlerOne")
next(w, r)
})
var myHandlerTwo = MyHandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
fmt.Println("use myHandlerTwo")
next(w, r)
})
var loveFunc = func(w http.ResponseWriter, r *http.Request) {
fmt.Println("you come you see")
w.Write([]byte("i love golang"))
}
func get(handler http.HandlerFunc) MyHandlerFunc {
return func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
handler.ServeHTTP(w, r) // http.HandlerFunc实际调用f(w, r)
next(w, r) // 后面执行的handler,当然你也写成next.ServeHTTP(w, r),这和next(w, r)本质是一样的
}
}
func main() {
myHandlers := []MyHandler{myHandlerOne, myHandlerTwo, get(loveFunc)}
m := build(myHandlers)
mux := http.NewServeMux()
mux.Handle("/youqu", m)
http.ListenAndServe(":1234", mux)
}
显然我们看到myHandlerTwo,myHandlerTwo在函数的结尾处调用next(w, r), 其传参数为m.next.ServeHTTP,其本身为函数类型即:func, m.handler.ServeHTTP(w, r, m.next.ServeHTTP), 这里做了匿名转换,将其转换为http.HandlerFunc, 当然显示的转换是更加容易理解的, m.handler.ServeHTTP(w, r, http.HandlerFunc(m.next.ServeHTTP))。 当我们执行next(w, r)的时候其实执行就是m.next.ServeHTTP(w, r), 由此可见,中间件才能往下执行。
灵魂在于ServeHTTP函数和Handler接口,一个请求进来会调用ServeHTTP, 然后找到对应的handler, 对应下图的handle(w, req, ps)
handle如何执行呢? 他会调用Handler的ServeHTTP, 在我们的例子里就是middlerware的ServeHTTP.
大概中间件就是这样运行起来的, 如果你完全懂了,那就可以实战了。
完结。