最近温故了一下go web 编程
看到第一个实例的时候 ,上面写着一段当时没有搞明白的文字
“main 函数中的两个HTTP函数HandleFunc和ListenAndServe 怎么联系起来的?”
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello world,%s!", r.URL.Path)
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8090", nil)
}
书中解释了每一行的含义,却没有说明他们的关系。
这里补充一下当初的疑问:
http.HandleFunc("/", handler) ,这是个回调函数,浏览器访问的时候,才会调用,即便它写在前面,实际调用 handler函数的时候是在后面执行的。所以要先看后面的函数。
http.ListenAndServe(":8090", nil)
看一下它的原型
// ListenAndServe listens on the TCP network address addr and then calls
// Serve with handler to handle requests on incoming connections.
// Accepted connections are configured to enable TCP keep-alives.
//
// The handler is typically nil, in which case the DefaultServeMux is used.
//
// ListenAndServe always returns a non-nil error.
func ListenAndServe(addr string, handler Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServe()
}
这里面注释说handler默认是nil的情况下,handler 的值是DefaultServeMux.
在看一下:http.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)
}
http.HandleFunc操作的对象就是DefaultServeMux.
并没有结束,因为很多时候注释是不可靠的,我们要看到源码server的默认handler为什么是DefaultServeMux; 我们需要看看 handler的原型:
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
handler 是一个接口类型,实现了ServeHTTP函数即可的接口类型,server 的实现在这里,当handler为nil时候,handler被赋值为默认值。
func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
handler := sh.srv.Handler
if handler == nil {
handler = DefaultServeMux
}
if req.RequestURI == "*" && req.Method == "OPTIONS" {
handler = globalOptionsHandler{}
}
handler.ServeHTTP(rw, req)
}
网友评论