关于http包中的handler
3.4 节中提到了:Handler 在 http 包中是一个接口,其中包含 ServeHTTP 方法,然而我们在使用 http 包时,并不用显式地实现 ServeHTTP 方法,http 包会自动帮我们实现 ServeHTTP 方法,从而实现 Handler 接口。
3.4 节在这里讲的有一些简略,我重新梳理下自己梳理对这块实现的理解,顺带结合 go15.6 中 http 包的源码捋一捋路由规则注册的全过程:
我们在使用默认路由时,首先要做的就是向路由中注册路由规则:
http.HandleFunc("/", sayhelloName)
之后 http 包中的默认路由就会为我们添加这条路由规则:
- 首先,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) }
- 在 2465-2471 行,DefaultServeMux.HandleFunc 会调用 DefauleServeMux.Handle:注意调用 Handle 时的第二个参数 HandlerFunc (handler),这里将 handler 做了类型强转,把函数 handler 转成了 HandlerFunc 类型的函数,我们看一下 type Handler 的声明:
// 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)) }
在 2034-2043 行,定义了 HandlerFunc 类型与 HandlerFunc.ServeHTTP 方法,注意 HandlerFunc.ServeHTTP 的实现:“f (w, r)”,此处表明调用 HandlerFunc (w, r) 其实就是调用 HandlerFunc.ServeHTTP (w, r)。// 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) }
至此,我们自定义的 handler 就实现了 ServeHTTP 方法,进而实现了 Handler 接口。 - DefaultServeMux.Handle 函数向 DefaultServeMux 的 map [string] muxEntry 中添加对应的 handler 和路由规则,就如 3.4 节中提到的一样。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: