一个躺平程序员的回光返照,内容大部分是有道翻译小部分是百度内容,如果有错误请在评论区提出,马上改
直接贴代码
// 设置运行模式 有三个值可选debug, release, test
gin.SetMode(utils.AppMode)
// 获取框架引擎
r :=gin.Default()
// 自定义方法,绑定路由方法
initAdminRouter(r)
initMobileRouter(r)
// 运行
r.Run(":" + utils.HttpPort)
gin.SetMode
// SetMode sets gin mode according to input string.
// SetMode根据输入字符串设置gin模式。
func SetMode(value string) {
if value == "" {
value = DebugMode
}
switch value {
case DebugMode: // debug
ginMode = debugCode
case ReleaseMode: // release
ginMode = releaseCode
case TestMode: // test
ginMode = testCode
default:
panic("gin mode unknown: " + value + " (available mode: debug release test)")
}
modeName = value
}
gin.Default()
debugPrintWARNINGDefault()
New()
Use()
Logger()
Recovery()
// Default returns an Engine instance with the Logger and Recovery middleware already attached.
// 默认返回一个已经附加了Logger和Recovery中间件的引擎实例。
func Default() *Engine {
// 验证go的版本号是否符合gin所需最低版本 go1.12+
debugPrintWARNINGDefault()
// 获取一个引擎实例, 获取的是引用类型实例
engine := New()
// 引擎实例bind Logger 和Recover中间件
engine.Use(Logger(), Recovery())
// 返回实例
return engine
}
// ginSupportMinGoVer 默认值为 12
func debugPrintWARNINGDefault() {
if v, e := getMinVer(runtime.Version()); e == nil && v <= ginSupportMinGoVer {
debugPrint(`[WARNING] Now Gin requires Go 1.12+.
`)
}
debugPrint(`[WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
`)
}
// 输入版本号go1.16.2返回大版本号 16
func getMinVer(v string) (uint64, error) {
first := strings.IndexByte(v, '.')
last := strings.LastIndexByte(v, '.')
if first == last {
return strconv.ParseUint(v[first+1:], 10, 64)
}
return strconv.ParseUint(v[first+1:last], 10, 64)
}
// 返回一个引擎实例(引用类型)
func New() *Engine {
// 提示信息
debugPrintWARNINGNew()
// 获取引擎实例
engine := &Engine{
// 初始化路由组
RouterGroup: RouterGroup{
// 路由组处理器
Handlers: nil,
basePath: "/",
root: true,
},
FuncMap: template.FuncMap{},
// 如果当前路由不能匹配,但存在带(不带)尾斜杠的路径处理程序,则启用自动重定向。例如,如果/foo/被请求,但是/foo的路由只存在,客户端被重定向到/foo, GET请求的状态码是301,其他所有请求方法的状态码是307
RedirectTrailingSlash: true,
RedirectFixedPath: false,
HandleMethodNotAllowed: false,
//如果启用,客户端IP将从请求头中解析,匹配存储在' (*gin.Engine). remoteipheaders '。
//如果没有获取IP,则返回到从' (*gin.Context). request . remoteaddr '中获取的IP。
ForwardedByClientIP: true,
// 启用获取客户端IP(ForwardedByClientIP为true)且通过(TrustedProxies)时获取指定头部信息。
RemoteIPHeaders: []string{"X-Forwarded-For", "X-Real-IP"},
TrustedProxies: []string{"0.0.0.0/0"},
// defaultAppEngine默认为false
AppEngine: defaultAppEngine,
// 启用RawPath
UseRawPath: false,
RemoveExtraSlash: false,
// 如果为true,则不转义路径值。如果UseRawPath为false(默认情况下),则UnescapePathValues有效为true,如url.Path会被使用,它已经没有转义。
UnescapePathValues: true,
// 分配最大上传大小 默认为32MB 32<<20
MaxMultipartMemory: defaultMultipartMemory,
// 创建长度为0的methodTrees切片且预留9个存储空间
trees: make(methodTrees, 0, 9),
// 定义默认定界符
delims: render.Delims{Left: "{{", Right: "}}"},
secureJSONPrefix: "while(1);",
}
// 将初始化完成的引擎实例赋值
engine.RouterGroup.engine = engine
/**
定义对象池(大概)并赋予默认值(大概,源码中为)
if x == nil && p.New != nil {
x = p.New()
}
return x
*/
engine.pool.New = func() interface{} {
return engine.allocateContext()
}
return engine
}
// 分配Context(上下文) 返回 Context(引用)
func (engine *Engine) allocateContext() *Context {
/**
Params为 []type Param struct {
Key string
Value string
}
engine.maxParams 默认为0
*/
v := make(Params, 0, engine.maxParams)
return &Context{engine: engine, params: &v}
}
// Engine的Use方法,不定参,参数的类型为HandlerFunc 返回IRoutes
func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {
engine.RouterGroup.Use(middleware...)
// 构建404请求 noRoute
engine.rebuild404Handlers()
// 构建405请求 noMethod
engine.rebuild405Handlers()
return engine
}
// RouteGroup.Use
// 在RouteGroup中添加处理程序(中间件) IRoutes
func (group *RouterGroup) Use(middleware ...HandlerFunc) IRoutes {
// Handlers是Group中的处理程序存储属性
group.Handlers = append(group.Handlers, middleware...)
return group.returnObj()
}
// 刚看到这儿的时候我还在想他是怎么实现的 HandlerFunc定义为 type HandlerFunc func(*Context),看完代码发现我是真的蠢
// 返回一个HandlerFunc
func Logger() HandlerFunc {
return LoggerWithConfig(LoggerConfig{})
}
// LoggerWithConfig instance a Logger middleware with config.
// LoggerWithConfig实例是一个带有config的Logger中间件。
// 返回值是一个HandleFunc
func LoggerWithConfig(conf LoggerConfig) HandlerFunc {
// 代码略过,框架主体走完在看这些中间件具体实现
// ...
// 返回一个匿名方法 666 果然人与人之间是不一样的
return func(c *Context) {
}
}
func Recovery() HandlerFunc {
return RecoveryWithWriter(DefaultErrorWriter)
}
// RecoveryWithWriter returns a middleware for a given writer that recovers from any panics and writes a 500 if there was one.
RecoveryWithWriter为给定的写入器返回一个中间件,该中间件可以从任何panics中恢复,如果有panics,则写入一个500。
func RecoveryWithWriter(out io.Writer, recovery ...RecoveryFunc) HandlerFunc {
// 如果传了后续参数则使用,如果没有则使用默认参, 默认参的一种实现方式
if len(recovery) > 0 {
return CustomRecoveryWithWriter(out, recovery[0])
}
return CustomRecoveryWithWriter(out, defaultHandleRecovery)
}
// CustomRecoveryWithWriter returns a middleware for a given writer that recovers from any panics and calls the provided handle func to handle it.
func CustomRecoveryWithWriter(out io.Writer, handle RecoveryFunc) HandlerFunc {
var logger *log.Logger
if out != nil {
logger = log.New(out, "\n\n\x1b[31m", log.LstdFlags)
}
return func(c *Context) {
// 延迟执行 最后执行, 如果多个defer则按栈的规则先进后出
// 入 func(1) func(2) func(3)
// 出 3 2 1
defer func() {
// ...
}()// 匿名方法立即执行方法
// c为Context Next()为继续执行下一个处理方法(大概)
c.Next()
}
}
// c.Next() 将handlers中的方法依次执行
func (c *Context) Next() {
c.index++
for c.index < int8(len(c.handlers)) {
c.handlers[c.index](c)
c.index++
}
}