martini.go
对路由采用正则表达式处理,最终转化成正则表达式。
添加route对应的调用栈
按照生成,验证,添加的步骤
route := newRoute(method, pattern, handlers) route.Validate() r.appendRoute(route)
martini会把任意类型的func 包装好,所以这里只要验证该类型是不是合适的func,因为一开始使用的是一个空的接口参数。
func validateHandler(handler Handler) { if reflect.TypeOf(handler).Kind() != reflect.Func { panic("martini handler must be a callable func") }}
这里可以看下go的类型定义
const ( Invalid Kind = iota Bool Int Int8 Int16 Int32 Int64 Uint Uint8 Uint16 Uint32 Uint64 Uintptr Float32 Float64 Complex64 Complex128 Array Chan Func Interface Map Ptr Slice String Struct UnsafePointer )
这里就加了个锁,安全的修改全局路由数组
func (r router) appendRoute(rt route) { r.routesLock.Lock() defer r.routesLock.Unlock() r.routes = append(r.routes, rt) }
我们要使用自己的handler,就需要将handler告诉go,这个其实也就是整个martini的真正起点。
func ListenAndServe(addr string, handler Handler) error { server := &Server{Addr: addr, Handler: handler} return server.ListenAndServe()}
这里我们传入m(martini):
logger.Fatalln(http.ListenAndServe(addr, m))
产生了较长的调用栈
这里通过反射的方式去调用不同的handler
func (r *routeContext) run() { for r.index < len(r.handlers) { handler := r.handlers[r.index] vals, err := r.Invoke(handler) if err != nil { panic(err) } r.index += 1 // if the handler returned something, write it to the http response if len(vals) > 0 { ev := r.Get(reflect.TypeOf(ReturnHandler(nil))) handleReturn := ev.Interface().(ReturnHandler) handleReturn(r, vals) } if r.Written() { return } } }