關於http包中的handler

Chloroplast發表於2020-12-22

3.4節中提到了:Handler在http包中是一個介面,其中包含ServeHTTP方法,然而我們在使用http包時,並不用顯式地實現ServeHTTP方法,http包會自動幫我們實現ServeHTTP方法,從而實現Handler介面。
3.4節在這裡講的有一些簡略,我重新梳理下自己梳理對這塊實現的理解,順帶結合go15.6中http包的原始碼捋一捋路由規則註冊的全過程:
我們在使用預設路由時,首先要做的就是向路由中註冊路由規則:

http.HandleFunc("/", sayhelloName)

之後http包中的預設路由就會為我們新增這條路由規則:

  1. 首先,2473~2483行,http.HandleFunc會呼叫DefaultServeMux.HandleFunc:
    // HandleFunc registers the handler function for the given pattern
    // in the DefaultServeMux.
    // The documentation for ServeMux explains how patterns are matched.
    func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
     DefaultServeMux.HandleFunc(pattern, handler)
    }
  2. 在2465-2471行,DefaultServeMux.HandleFunc會呼叫DefauleServeMux.Handle:
    // HandleFunc registers the handler function for the given pattern.
    func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
     if handler == nil {
         panic("http: nil handler")
     }
     mux.Handle(pattern, HandlerFunc(handler))
    }
    注意呼叫Handle時的第二個引數HandlerFunc(handler),這裡將handler做了型別強轉,把函式handler轉成了HandlerFunc型別的函式,我們看一下type Handler的宣告:
    // The HandlerFunc type is an adapter to allow the use of
    // ordinary functions as HTTP handlers. If f is a function
    // with the appropriate signature, HandlerFunc(f) is a
    // Handler that calls f.
    type HandlerFunc func(ResponseWriter, *Request)
    // ServeHTTP calls f(w, r).
    func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
     f(w, r)
    }
    在2034-2043行,定義了HandlerFunc型別與HandlerFunc.ServeHTTP方法,注意HandlerFunc.ServeHTTP的實現:“f(w, r)”,此處表明呼叫HandlerFunc(w, r)其實就是呼叫HandlerFunc.ServeHTTP(w, r)。
    至此,我們自定義的handler就實現了ServeHTTP方法,進而實現了Handler介面。
  3. DefaultServeMux.Handle函式向DefaultServeMux 的 map [string] muxEntry中新增對應的handler和路由規則,就如3.4節中提到的一樣。
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章