首先,熟悉http协议的都知道,http协议是基于TCP实现的。
http服务器的工作方式大概就是监听socket端口,接受连接,获取到请求,处理请求,返回响应。
所以,对应的会有几个部分
Request:用户请求的信息。post、get、url等这些信息
Response: 返回给客户端的信息
Conn: 用户每次的连接请求
Handler:处理请求和返回信息的逻辑处理
func hello(w http.ResponseWriter,r *http.Request) { w.Write([]byte("hello!\r\n")) } func main() { http.HandleFunc("/",hello) err := http.ListenAndServe("0.0.0.0:8889",nil) if err != nil { fmt.Println(err) } }
问题:函数 http.HandleFunc(“/”,hello) 里面发生了什么?
先分析一下http.HandleFunc()这个函数。直接进入函数HandleFunc的声明,源码如下
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { DefaultServeMux.HandleFunc(pattern, handler) }
DefaultServeMux = 默认的一个go web的路由器 在源代码中的声明如下
type ServeMux struct { mu sync.RWMutex m map[string]muxEntry hosts bool // whether any patterns contain hostnames } type muxEntry struct { explicit bool h Handler pattern string } // NewServeMux allocates and returns a new ServeMux. func NewServeMux() *ServeMux { return &ServeMux{m: make(map[string]muxEntry)} } // DefaultServeMux is the default ServeMux used by Serve. var DefaultServeMux = NewServeMux()
这里DefaultServeMux调用了HandleFunc(),参数就是传进来的“/”和HandleFunc(定义一个函数类型,就可以把函数作为参数传入)
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { if handler == nil { panic("http: nil handler") } mux.Handle(pattern, HandlerFunc(handler)) }
HandlerFunc 是ServeMux 结构体的方法,这里先分析HandlerFunc(handler),也就是把func(ResponseWriter, *Request)函数类型转换为HandlerFunc类型(注意!是HandlerFunc,不是HandleFunc)【其实就是定制规则个人理解】
HandlerFunc这里定义了一个func(ResponseWriter, *Request)的函数类型,HandlerFunc(handler)实际上就是handler本身。为什么这么做?
type HandlerFunc func(ResponseWriter, *Request) // ServeHTTP calls f(w, r). func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { f(w, r) }
HandlerFunc实现了ServeHTTP(w ResponseWriter, r *Request) 这个方法!!!!里面只有一行代码f(w, r),也就是说实际上是调用handler,也就是我们一开始在http.HandleFunc(“/”, HandleRequest)中自己定义的函数HandleRequest。
而 HandlerFunc 实现了 ServeHTTP的方法,其实就是实现了 Handler 接口。
HandlerFunc实现Handler接口里面的方法。跟Java里面的接口一样,任何实现接口的类型,都可以向上转换为该接口类型。这就意味着HandlerFunc类型的值可以自动转换为Handler类型的值作为参数传进任何函数中。这很重要!回头看看muxEntry结构体里面的两个变量pattern string和h Handler,不正好对应刚才传入的参数pattern, HandlerFunc(handler)吗!!
总结一下:
所以,HandlerFunc(handler)就是一个适配器模式!HandlerFunc实现Handler接口,ServeHTTP方法里面调用的实际上是我们一开始定义的函数HandleRequest。
这样的一个好处就是,func(ResponseWriter,*Request) -> HandlerFunc -> Handler ,那定义的函数HandleRequest可以作为Handler类型的一个参数。调用Handler的ServeHTTP方法,也就是调用定义的函数HandleRequest。
理解完HandlerFunc(handler),再来看看整句mux.Handle(pattern, HandlerFunc(handler))
func (mux *ServeMux) Handle(pattern string, handler Handler) { mux.mu.Lock() defer mux.mu.Unlock() if pattern == "" { panic("http: invalid pattern") } if handler == nil { panic("http: nil handler") } if _, exist := mux.m[pattern]; exist { panic("http: multiple registrations for " + pattern) } if mux.m == nil { mux.m = make(map[string]muxEntry) } e := muxEntry{h: handler, pattern: pattern} mux.m[pattern] = e if pattern[len(pattern)-1] == '/' { mux.es = appendSorted(mux.es, e) } if pattern[0] != '/' { mux.hosts = true } }
个人思考:
原文地址:http://www.cnblogs.com/zh718594493/p/16911829.html