先贴一段代码服务器

package main

import (
    "net/http"
    "fmt"
    "log"
)

func hello(w http.ResponseWriter, r *http.Request)  {
    r.ParseForm()
    fmt.Printf("%+v\n", *r.URL)
    fmt.Fprintln(w, "Hello world")
}

func main() {
    http.HandleFunc("/", hello)
    err := http.ListenAndServe(":9090", nil)
    if err != nil {
        log.Fatal(err)
    }
}

这里监听本地的9090端口,使用 http.HandleFunc 将URL为“/”的请求将其转向名为hello的方法。这是比较常见的Golang的简单Web的实现,可是看着会以为很奇怪,建议先把代码跑起来,而后咱们再来看看源码中Handler的定义先。并发

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

如代码中所示,Handler实际上一个接口,实现了 ServeHTTP(ResponseWriter, *Request) 这个函数,就至关于实现了一个Handler。通俗讲Handler就是处理输入输出流的函数,将Handler注册到路由器,等同于将特定的URL跟这个函数绑定起来,当客户端请求访问这个URL,路由器就会使用这个函数进行操做。
可能会有童鞋会疑问,hello这个函数并非一个Handler,为何能够做为Handler注册一个URL。这是由于这里有一个函数叫作HandleFunc,这里就讲讲HandleFunc的原理吧。先把源码列出来:函数

func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    DefaultServeMux.HandleFunc(pattern, handler)
}

HandleFunc传入一个字符串(URL)和一个func(ResponseWriter, Request),hello这个函数是符合func(ResponseWriter, Request)的要求的,而后使用DefaultServeMux进行处理,DefaultServeMux又是什么?在server.go的源码中能够轻松找到DefaultServeMux的定义性能

type ServeMux struct {
    mu    sync.RWMutex
    m     map[string]muxEntry
    hosts bool // whether any patterns contain hostnames
}
....
// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = &defaultServeMux

var defaultServeMux ServeMux

由源码能够知道DefaultServeMux至关于一个公共的路由,一个公有变量,URL和Handle就是注册到这个路由上的。须要注意的是ServeMux的成员变量,有一个sync.RWMutex,了解过Golang并发的应该知道,这是一个读写锁(Mutiple read,single write lock, 多读单写锁,容许多个读操做并行执行,但写操做会彻底互斥,在读取操做比较频繁时比sync.Mutex有着更好的性能表现),这应该也是考虑到做为Web服务器,读取操做会比较频繁。接下来看mux.Handle(pattern, HandlerFunc(handler))去到哪一步,应该看到这里有一个函数HandlerFunc(handler):code

type HandlerFunc func(ResponseWriter, *Request)

// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r)
}

看到这里你就应该明白,为何hello这个函数没有实现Handler方法也是一个Handler,由于HandlerFunc把hello强制实现ServeHTTP(w ResponseWriter, r *Request),因此hello这个函数也就是一个Handler。orm

这里是路由的最后一步了server

type muxEntry struct {
    h       Handler
    pattern string
}

// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
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)
    }
    mux.m[pattern] = muxEntry{h: handler, pattern: pattern}

    if pattern[0] != '/' {
        mux.hosts = true
    }
}

公有变量DefaultServeMux将Handler注册,这里就用到了读写锁以及一个私有结构muxEntry,到这里,路由注册就结束了。接口