1、定义处理器函数
2、绑定路由处理器函数
3、启动服务并监听服务端口
package main
import (
"log"
"net/http"
)
// 1、定义处理器函数
func helloHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello world"))
}
func main() {
// 2、绑定 路由"/hello"和处理器函数helloHandler
http.HandleFunc("/hello", helloHandler)
// 3、启动服务并监听8090端口
err := http.ListenAndServe("localhost:8090", nil)
if err != nil {
log.Fatal(err)
}
}
1、从hello world代码中可以看到HandleFunc的功能是绑定路由处理器函数,跟进HandleFunc源码
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
DefaultServeMux.HandleFunc(pattern, handler)
}
2、跟进DefaultServeMux可以看到是ServeMux结构体类型变量
var DefaultServeMux = &defaultServeMux
var defaultServeMux ServeMux
3、跟进ServeMux结构体,可以看到包含一个map[string]muxEntry类型字段m
type ServeMux struct {
mu sync.RWMutex
m map[string]muxEntry
es []muxEntry // slice of entries sorted from longest to shortest.
hosts bool // whether any patterns contain hostnames
}
4、跟进DefaultServeMux.HandleFunc,DefaultServeMux.HandleFunc内部调用mux.Handle
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
if handler == nil {
panic("http: nil handler")
}
mux.Handle(pattern, HandlerFunc(handler))
}
5、跟进mux.Handle(已略去部分代码)
func (mux *ServeMux) Handle(pattern string, handler Handler) {
// 封装路由器及处理器函数
e := muxEntry{h: handler, pattern: pattern}
// 绑定路由与对应处理器函数
mux.m[pattern] = e
}
综上可以看到http.HandleFunc的功能是绑定路由及处理器函数并注册到DefaultServeMux的map内。
1、跟进源码,看到内部调用server.ListenAndServe()
func ListenAndServe(addr string, handler Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServe()
}
2、跟进server.ListenAndServe()(已略去部分代码)
func (srv *Server) ListenAndServe() error {
return srv.Serve(ln)
}
3、跟进srv.Serve(ln) (已略去部分代码)最后一行看到,启动了一个协程 调用 c.serve(connCtx)
func (srv *Server) Serve(l net.Listener) error {
go c.serve(connCtx)
}
4、跟进c.serve(connCtx)(已略去部分代码)看到一行如下代码
serverHandler{c.server}.ServeHTTP(w, w.req)
5、跟进ServeHTTP(w, w.req)(已略去部分代码),可以看到当handler为nil时使用默认Handler即DefaultServeMux
func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
handler := sh.srv.Handler
if handler == nil {
handler = DefaultServeMux
}
handler.ServeHTTP(rw, req)
}
6、跟进DefaultServeMux.ServeHTTP(rw, req)(已略去部分代码)
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
// 查询已注册的处理器函数
h, _ := mux.Handler(r)
// 调用注册的处理器函数
h.ServeHTTP(w, r)
}
7、跟进mux.Handler( r )到最后一行代码(已略去部分代码)
func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
return mux.handler(host, r.URL.Path)
}
8、跟进mux.handler(host, r.URL.Path),看到当找不到对应处理器函数时返回NotFoundHandler 404页面处理器函数
func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
mux.mu.RLock()
defer mux.mu.RUnlock()
// Host-specific pattern takes precedence over generic ones
if mux.hosts {
h, pattern = mux.match(host + path)
}
if h == nil {
h, pattern = mux.match(path)
}
if h == nil {
h, pattern = NotFoundHandler(), ""
}
return
}
9、跟进mux.match(path),可以看到处理器函数就是http.HandleFunc注册到map中的
func (mux *ServeMux) match(path string) (h Handler, pattern string) {
v, ok := mux.m[path]
if ok {
return v.h, v.pattern
}
}
hello world 中http.ListenAndServe(“localhost:8090”, nil)出入的http.Handler是nil,当handler为nil时使用默认的handler。现在传入一个自定义http.Handler
package main
import (
"log"
"net/http"
)
type myHandler struct {
}
func (myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/hello":
helloHandler(w, r)
default:
http.NotFound(w, r)
}
}
func helloHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello world"))
}
func main() {
var handler myHandler
err := http.ListenAndServe("localhost:8090", handler)
if err != nil {
log.Fatal(err)
}
}