Go negroni 對(duì)于第三方中間件的使用

本文介紹了 go 語(yǔ)言 negroni 中間件。
negroni本身是一個(gè)中間件,不過(guò)它也提供了拓展,以幫助我們更簡(jiǎn)單地實(shí)現(xiàn)自己想要的功能的中間件。那么,我們究竟該如何實(shí)現(xiàn)中間件,才能能夠封裝到negroni中,從而通過(guò)negroni來(lái)調(diào)用呢?可以通過(guò)一個(gè)簡(jiǎn)單的例子分析:
package?main
import?(
"fmt"
"net/http"
"github.com/urfave/negroni"
"github.com/phyber/negroni-gzip/gzip"
)
func?main()?{
mux?:=?http.NewServeMux()
mux.HandleFunc("/",?func(w?http.ResponseWriter,?req?*http.Request)?{
fmt.Fprintf(w,?"Welcome?to?the?home?page!")
})
n?:=?negroni.Classic()?//創(chuàng)建一個(gè)negroni
n.Use(gzip.Gzip(gzip.DefaultCompression))
n.UseHandler(mux)
n.Run(":3000")
}
我們從negroni創(chuàng)建之后開(kāi)始分析。n.UseHandler(mux)函數(shù):
n.UseHandler(mux)
????+func?(n?*Negroni)?UseHandler(handler?http.Handler)
????????|n.Use(Wrap(handler))
????????+func?Wrap(handler?http.Handler)?Handler
????????????|return?HandlerFunc(func(rw?http.ResponseWriter,?r?*http.Request,?next?http.HandlerFunc)
????????+func?(n?*Negroni)?Use(handler?Handler)
????????????|n.handlers?=?append(n.handlers,?handler)
????????????|n.middleware?=?build(n.handlers)
????????????+func?build(handlers?[]Handler)?middleware
????????????????|return?middleware{handlers[0],?&next}
調(diào)用n.UseHandler(mux)函數(shù)的過(guò)程中,同樣也調(diào)用了n.Use()函數(shù)。說(shuō)明negroni對(duì)于第三方中間件的使用是從n.UseHandler開(kāi)始的。
接下來(lái),一起來(lái)分析追蹤過(guò)程中遇到的函數(shù):
1. UseHandler
該函數(shù)返回將handler傳遞給Wrap()函數(shù)
func?(n?*Negroni)?UseHandler(handler?http.Handler)?{
????n.Use(Wrap(handler))
}
2. Wrap
該函數(shù)對(duì)handler進(jìn)行封裝,編程固定format的handler。
func?Wrap(handler?http.Handler)?Handler?{
????return?HandlerFunc(func(rw?http.ResponseWriter,?r?*http.Request,?next?http.HandlerFunc)?{
????????handler.ServeHTTP(rw,?r)
????????next(rw,?r)
????})
}
3. Use
該函數(shù)則將handler添加到Negroni結(jié)構(gòu)體中。其中,midlleware是一個(gè)鏈表。
func?(n?*Negroni)?Use(handler?Handler)?{
????if?handler?==?nil?{
????????panic("handler?cannot?be?nil")
????}
????n.handlers?=?append(n.handlers,?handler)
????n.middleware?=?build(n.handlers)
}
+-----------------------------------------+
type?Negroni?struct?{
????middleware?middleware
????handlers???[]Handler
}
type?middleware?struct?{
????handler?Handler
????next????*middleware
}
4. build
如果你了解C/C++,這個(gè)函數(shù)很好理解。它僅僅是一個(gè)迭代函數(shù),實(shí)現(xiàn)了middleware鏈表的構(gòu)建。
func?build(handlers?[]Handler)?middleware?{
????var?next?middleware
????if?len(handlers)?==?0?{
????????return?voidMiddleware()
????}?else?if?len(handlers)?>?1?{
????????next?=?build(handlers[1:])
????}?else?{
????????next?=?voidMiddleware()
????}
????return?middleware{handlers[0],?&next}
}
5. 對(duì)ServerHTTP的處理
同時(shí),我們也要清楚Handler是一個(gè)接口,一個(gè)Handler對(duì)象必須實(shí)現(xiàn)Handler接口。Handler接口定義如下:
type?Handler?interface?{
????ServeHTTP(ResponseWriter,?*Request)
}
negroni對(duì)ServeHTTP做了哪些處理呢?通過(guò)以下三個(gè)函數(shù)可以了解:
//函數(shù)類(lèi)型,使用HandleFunc會(huì)調(diào)用
//func(rw?http.ResponseWriter,?r?*http.Request,?next?http.HandlerFunc)的實(shí)現(xiàn)
type?HandlerFunc?func(rw?http.ResponseWriter,?r?*http.Request,?next?http.HandlerFunc)
//調(diào)用函數(shù)實(shí)現(xiàn)
func?(h?HandlerFunc)?ServeHTTP(rw?http.ResponseWriter,?r?*http.Request,?next?http.HandlerFunc)?{
????h(rw,?r,?next)
}
//實(shí)現(xiàn)ServerHTTP的封裝
func?(m?middleware)?ServeHTTP(rw?http.ResponseWriter,?r?*http.Request)?{
????m.handler.ServeHTTP(rw,?r,?m.next.ServeHTTP)
}
接下來(lái),我們追蹤n.Run(“:3000”)函數(shù):
n.Run(":3000")
????+func?(n?*Negroni)?Run(addr?...string)
????|finalAddr?:=?detectAddress(addr...)
????????+func?detectAddress(addr?...string)?string
????|l.Fatal(http.ListenAndServe(finalAddr,?n))
????????+func?ListenAndServe(addr?string,?handler?Handler)?error
????????|......
negroni.Run解析address后,最終調(diào)用了http.ListenAndServe來(lái)實(shí)現(xiàn)服務(wù)器。這一步,才最終完成了服務(wù)器的搭建;所有的handler都交付給了http.ListenAndServe去實(shí)現(xiàn)。
關(guān)于negroni對(duì)于第三方中間件的使用就分析到這里了。
轉(zhuǎn)自:blog.csdn.net/Kiloveyousmile/article/details/78740242
文章轉(zhuǎn)載:Python編程學(xué)習(xí)圈
(版權(quán)歸原作者所有,侵刪)

點(diǎn)擊下方“閱讀原文”查看更多
