Negroni是一个http.Handle,因为他实现了
func (n *Negroni) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
n.middleware.ServeHTTP(NewResponseWriter(rw), r)
}
所以Negroni可以作为http.listenAndServe的一个入口。
func (n *Negroni) Run(addr ...string) {
l := log.New(os.Stdout, "[negroni] ", 0)
finalAddr := detectAddress(addr...)
l.Printf("listening on %s", finalAddr)
l.Fatal(http.ListenAndServe(finalAddr, n))
}
程序会在适当时候调用Negroni.ServeHTTP。
所有中间件,包括路由,都是一个被包装起来的http.Handle。
中间件的构成为:
type middleware struct {
handler Handler
next *middleware
}
Negroni的构成为:
type Negroni struct {
middleware middleware
handlers []Handler
}
可以看到,Negroni中包含有一个“首中间件”,和所有与中间件相关的Handler。middleWare很像链表的一个节,Negroni保存着首链节,然后依次访问所有中间件,(即依次调用中间件的Handler)。
这些中间件的Handler各有不同。
如"路由中间件"本身包含有一个Map数据结构,保存着路径以及对应的处理函数。"路由中间件"的Handler就是遍历这个Map,找到合适的处理函数进行处理。而如Log中间件,Recovery中间件等,则是具有处理Log和恢复相关的功能。
注意,http.Handler和Negroni.Handler不一样。
//Negroni.Handler
type Handler interface {
ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)
}
//http.Handler
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}