最主要的package : gin

最主要的struct: Engine

Engine 是整个framework的实例,它包含了muxer, middleware, configuration settings. 通过New() 或者Default()来创建一个Engine 的实例。

type Engine struct {
RouterGroup // Enables automatic redirection if the current route can't be matched but a
// handler for the path with (without) the trailing slash exists.
// For example if /foo/ is requested but a route only exists for /foo, the
// client is redirected to /foo with http status code 301 for GET requests
// and 307 for all other request methods.
RedirectTrailingSlash bool // If enabled, the router tries to fix the current request path, if no
// handle is registered for it.
// First superfluous path elements like ../ or // are removed.
// Afterwards the router does a case-insensitive lookup of the cleaned path.
// If a handle can be found for this route, the router makes a redirection
// to the corrected path with status code 301 for GET requests and 307 for
// all other request methods.
// For example /FOO and /..//Foo could be redirected to /foo.
// RedirectTrailingSlash is independent of this option.
RedirectFixedPath bool // If enabled, the router checks if another method is allowed for the
// current route, if the current request can not be routed.
// If this is the case, the request is answered with 'Method Not Allowed'
// and HTTP status code 405.
// If no other Method is allowed, the request is delegated to the NotFound
// handler.
HandleMethodNotAllowed bool
ForwardedByClientIP bool // #726 #755 If enabled, it will thrust some headers starting with
// 'X-AppEngine...' for better integration with that PaaS.
AppEngine bool // If enabled, the url.RawPath will be used to find parameters.
UseRawPath bool // If true, the path value will be unescaped.
// If UseRawPath is false (by default), the UnescapePathValues effectively is true,
// as url.Path gonna be used, which is already unescaped.
UnescapePathValues bool // Value of 'maxMemory' param that is given to http.Request's ParseMultipartForm
// method call.
MaxMultipartMemory int64 delims render.Delims
secureJsonPrefix string
HTMLRender render.HTMLRender
FuncMap template.FuncMap
allNoRoute HandlersChain
allNoMethod HandlersChain
noRoute HandlersChain
noMethod HandlersChain
pool sync.Pool
trees methodTrees
}

获取一个gin Engin的实例:r := gin.Default()

查看gin.Default()方法的实现:

// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New() #实例化一个engine
engine.Use(Logger(), Recovery())
return engine
}

  查看New()的实现:

// New returns a new blank Engine instance without any middleware attached.
// By default the configuration is:
// - RedirectTrailingSlash: true
// - RedirectFixedPath: false
// - HandleMethodNotAllowed: false
// - ForwardedByClientIP: true
// - UseRawPath: false
// - UnescapePathValues: true
func New() *Engine {
debugPrintWARNINGNew()
engine := &Engine{
RouterGroup: RouterGroup{
Handlers: nil,
basePath: "/",
root: true,
},
FuncMap: template.FuncMap{},
RedirectTrailingSlash: true,
RedirectFixedPath: false,
HandleMethodNotAllowed: false,
ForwardedByClientIP: true,
AppEngine: defaultAppEngine,
UseRawPath: false,
UnescapePathValues: true,
MaxMultipartMemory: defaultMultipartMemory,
trees: make(methodTrees, 0, 9),
delims: render.Delims{Left: "{{", Right: "}}"},
secureJsonPrefix: "while(1);",
}
engine.RouterGroup.engine = engine
engine.pool.New = func() interface{} { //这里定义了engine.pool.New方法,所以在Get()的时候,如果为nil,那么直接执行New 方法
return engine.allocateContext()
}
return engine
}

 如果engine.pool.New被执行,那么将返回一个*Context类型的指针。

func (engine *Engine) allocateContext() *Context {
return &Context{engine: engine}
}

然后调用r.Run(":8080"), 在本地网卡上监听8080端口,等待连接。实际上调用的是:http.ListenAndServe(address, engine)

查看http.ListenAndServe方法:

func ListenAndServe(addr string, handler Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServe()
}

 它且将addr 和handler作为参数实例化了一个Server, 然后调用server.ListenAndServe()方法等待连接。

查看Handler的定义:

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

 它是一个interface, 那么也就是说它作为参数的话,那么这个struct必须实现ServeHTTP(ResponseWriter, *Request) 这个方法。

在gin.go中查看ServeHTTP方法的定义:

// ServeHTTP conforms to the http.Handler interface.
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
c := engine.pool.Get().(*Context) 返回的是New()里面定义的func,然后执行。
c.writermem.reset(w)
c.Request = req
c.reset() engine.handleHTTPRequest(c) engine.pool.Put(c)
}

 这里的engine.pool.Get().(*Context) 方法,实际上执行的是上面的New方法,所以得到的是一个Context类型的指针。

分析到这里,也就是说,如果有一个HTTP请求到来,那么会先触发ServeHTTP方法得到一个Context请求上下文,然后调用engine.handleHTTPRequest(C),处理这个请求,同时将处理的内容写入到http.ResponseWriter中。

关于engine.handleHTTPRequest()如何实现的,参考gin 路由表的设计

处理完以后为什么还要执行engine.pool.Put(c)呢?

因为:engine.pool需要一个buffer来存储内容,当下一个请求到达的时候,就可以直接来使用,避免又调用一次New函数,节省了内存。

最新文章

  1. java io流 图片和字符串之间的转换
  2. ImitateLogin新增插件机制以及又一个社交网站的支持
  3. jQuery中添加/改变/移除改变CSS样式例子
  4. error MSB3027: Could not copy "xxx.dll" to "xxx.dll". Exceeded retry count of 10. Failed.
  5. Codevs 1648 最大和
  6. java对Ldap操作4
  7. Learning Cocos2d-x for WP8(4)——中文显示
  8. opencv使用convexityDefects计算轮廓凸缺陷
  9. ROS机器人程序设计(原书第2版)补充资料 (零) 源代码、资料和印刷错误修订等 2017年01月01日更新
  10. GitHub网站使用的基础入门
  11. Apache 开启压缩传输
  12. 【转】Pandas的Apply函数——Pandas中最好用的函数
  13. git lg 配置
  14. jquery实现星级评分
  15. 在Spark上通过BulkLoad快速将海量数据导入到Hbase
  16. Configure First SpringMVC project in IntelliJ IDEA(fail)
  17. 走向Node与Webpack 之路 - CommonJS 模块化
  18. bzoj千题计划111:bzoj1021: [SHOI2008]Debt 循环的债务
  19. 《移动App测试实战》读书笔记
  20. WPF MVVM从入门到精通1:MVVM模式简介

热门文章

  1. jQuery实现购物车物品数量的加减
  2. Vue系列之 => 命名视图实现经典布局
  3. codeforces 982B Bus of Characters
  4. flask 操作数据时,db的要在app.config设置之后声明:如app.config['SQLALCHEMY_DATABASE_URI']
  5. CentOS6.5升级GCC4.8
  6. 使用 mysqladmin debug 查看死锁信息
  7. poj 3294 Life Forms - 后缀数组 - 二分答案
  8. Day 10733 使用独立安装包安装.Net Framework 4.6.2时,提示『无法建立到信任根颁发机构的证书链』
  9. 使用Flask部署机器学习模型
  10. TCP协议三次握手、四次挥手