责任链模式
1 在gin中通过Next()函数来调用前缀树最下面的处理链上的函数,主要是中间件来调用的,如日志中间件Logger(),自己的路由函数也可以调用,但一般不用,因为自己定义的路由函数大多是顺序执行,
特别注意处理链上的函数实际上并不是严格顺序执行的,通过改变Next()在函数中调用的位置可以直接改变执行顺序,
// Next()函数一般放在中间件函数中,它只有三种情况, // 如果放在函数开头,则这个函数最后才执行 // 如果放在函数中间,则就是洋葱模型,之前的先执行,之后的最后才执行 // 如果放在函数末尾,则就是顺序执行 // 从这里可以看出,自己定义的路由函数不添加Next()函数也可以,默认会顺序执行, // 换句话说自己的路由函数不添加Next函数和添加在末尾是等效的, func (c *Context) Next() { c.index++ for c.index < int8(len(c.handlers)) { c.handlers[c.index](c) c.index++ } } // Context中的index变量用于控制责任链上的索引执行到哪个了,在reset中进行了初始化,为-1, func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) { c := engine.pool.Get().(*Context) c.writermem.reset(w) c.Request = req c.reset() engine.handleHTTPRequest(c) engine.pool.Put(c) }
下面是一个很好的例子,在自己定义的路由函数中注释掉Next()函数就是顺序执行,不注释掉就不是,因为有个Next()函数放在了中间,