最近打算用golang做项目,看了一下golang的资料,顺便做一下笔记,以供参考,复习.
由于对golang的熟悉度还不是很高,写的有点生疏了,也希望能对大家有帮助吧.
示例源码:
packagemain
import(
"log"
"net/http"
)
func sayHelloName (w http.ResponseWriter,r*http.Request){
w.Write([]byte("hello,world!"))
}
func main(){
http.HandleFunc("/",sayHelloName)
err:=http.ListenAndServe(":8080",nil)
iferr!=nil{
log.Fatal("ListenAndServe:",err)
}
}
http.HandleFunc("/",sayHelloName) 解读打开源码包 server.go跳到1775行,看到函数
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {DefaultServeMux.HandleFunc(pattern, handler)}
DefaultServeMux的结构如下:type ServeMux struct {mu sync.RWMutexm map[string]muxEntryhosts bool // whether any patterns contain hostnames}
type muxEntry struct {explicit boolh Handlerpattern string}
DefaultServeMux是一个全局变量在server.go的 1595 行创建的func NewServeMux() *ServeMux { return &ServeMux{m: make(map[string]muxEntry)} }var DefaultServeMux = NewServeMux()接着跟进 DefaultServeMux.HandleFunc(pattern, handler)func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {mux.Handle(pattern, HandlerFunc(handler))}
在这个函数里面把前面传进来的helloWorld 函数转换成 HandlerFunc而 HandlerFunc的类型如下:再跟进Handle函数type HandlerFunc func(ResponseWriter, *Request)// ServeHTTP calls f(w, r).func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {f(w, r)}
HandlerFunc类型实现了方法 ServeHTTP
func (mux *ServeMux) Handle(pattern string, handler Handler) {mux.mu.Lock() // 因为map是全局的,涉及到全局调用,因此加锁defer mux.mu.Unlock()if pattern == "" {panic("http: invalid pattern " + pattern)}if handler == nil {panic("http: nil handler")}if mux.m[pattern].explicit {panic("http: multiple registrations for " + pattern)}mux.m[pattern] = muxEntry{explicit: true, h: handler, pattern: pattern} // 这里注册路由err := http.ListenAndServe(":8080",nil)解读跟进函数ListenAndServe,内容如下func ListenAndServe(addr string, handler Handler) error {server := &Server{Addr: addr, Handler: handler}return server.ListenAndServe()}
而参数 Handler 是一个接口,内容如下看到 server := &Server{Addr: addr, Handler: handler} 这句type Handler interface {ServeHTTP(ResponseWriter, *Request)}
因为我们在调用ListenAndServe时,第二个参数是nil,所以这里的handle是nil
继续跟进ListenAndServe内容如下func (srv *Server) ListenAndServe() error {addr := srv.Addrif addr == "" {addr = ":http"}ln, err := net.Listen("tcp", addr) // 在这里调用了tcp监听了if err != nil {return err}return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})}
跟进 Serve,可以看到在该函数里面调用了rw, e := l.Accept(),在接受连接的函数并且每一个连接 go c.serve() 创建了一个携程跟进 c.serve() 可以看到在函数里面对请求调用了 ServeHTTPserverHandler{c.server}.ServeHTTP(w, w.req)跟进去内容如下func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {handler := sh.srv.Handlerif handler == nil { // 在在这里判断用哪个 handler了handler = DefaultServeMux}if req.RequestURI == "*" && req.Method == "OPTIONS" {handler = globalOptionsHandler{}}handler.ServeHTTP(rw, req)}
很显然看出了,如果在调用err:=http.ListenAndServe(":8080",nil)时,第二个参数是我们自定义的Handler的话则调用我们的,否则的话就默认调用 DefaultServeMux
由此可以看出,如果我们要自定义Handler的话只要实现ServeHTTP(ResponseWriter, *Request)方法即可例子如下:
package mainimport ("fmt""log""net/http")
type MyHandler struct {}
func (this *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {fmt.Println("myHanlder")w.Write([]byte("myHanlder"))}
func main() {err := http.ListenAndServe(":8080", &MyHandler{})if err != nil {log.Fatal("ListenAndServe: ", err)}}
有疑问加站长微信联系(非本文作者)