beego源码分析(二)——起源 - Go语言中文社区

beego源码分析(二)——起源


起源

前言

我们在初探中,从beego.run和routers package两个方向分析整个服务的框架与golang底层的框架一致。但我们还有一些疑问?

实际上beego的入口只有beego.Run,怎么与routers具体联系起来的呢?

接下来我们一步步看下beego.Run背后的逻辑。

一、import & init

我们首先从程序最开始的import部分开始看。

import (

    _ "test/routers"

    "github.com/astaxie/beego"
)

我们知道golang的初始化的方向如下:
初始化方向

按照这个方向,我们可以知道先调用routers package init,在routers内再次import “github.com/astaxie/beego”,因此先调用beego package init,然后调用routers package init。

1.beego init

代码如下:

var (
    // BeeApp is an application instance
    BeeApp *App
)

func init() {
    // create beego application
    BeeApp = NewApp()
}

func NewApp() *App {
    cr := NewControllerRegister()
    app := &App{Handlers: cr, Server: &http.Server{}}
    return app
}

func NewControllerRegister() *ControllerRegister {
    cr := &ControllerRegister{
        routers:  make(map[string]*Tree),
        policies: make(map[string]*Tree),
    }
    cr.pool.New = func() interface{} {
        return beecontext.NewContext()
    }
    return cr
}

以上init完成了BeeApp的初始化,同时,初始化了Handler及Server的值(这是两个很重的参数,后面将会用到),在这里我们可以看到Handler的类型是ControllerRegister,在处理请求时将会用到。

2.routers init

routers init主要是路由的声明,例如:

ns :=
beego.NewNamespace("/v1",
    beego.NSCond(func(ctx *context.Context) bool {
        if ctx.Input.Domain() == "api.beego.me" {
            return true
        }
        return false
    }),
    beego.NSBefore(auth),
    beego.NSGet("/notallowed", func(ctx *context.Context) {
        ctx.Output.Body([]byte("notAllowed"))
    }),
    beego.NSRouter("/version", &AdminController{}, "get:ShowAPIVersion"),
    beego.NSRouter("/changepassword", &UserController{}),
    beego.NSNamespace("/shop",
        beego.NSBefore(sentry),
        beego.NSGet("/:id", func(ctx *context.Context) {
            ctx.Output.Body([]byte("notAllowed"))
        }),
    ),
    beego.NSNamespace("/cms",
        beego.NSInclude(
            &controllers.MainController{},
            &controllers.CMSController{},
            &controllers.BlockController{},
        ),
    ),
)
//注册 namespace
beego.AddNamespace(ns)

我们同样在初探中提过beego.Get、beego.Router、beego.AutoRouter、beego.Include、beego.AddNamespace等方式声明的路由最终存储在BeeApp.Handlers.routers。

二、beego.Run

beego.Run代码如下:

func Run(params ...string) {
    ...
    BeeApp.Run()
}

beego.Run最终调用了之前已经初始化了的BeeApp,

// Run beego application.
func (app *App) Run() {
    ...
    app.Server.Handler = app.Handlers
    app.Server.ReadTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second
    app.Server.WriteTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second
    app.Server.ErrorLog = logs.GetLogger("HTTP")

    // run graceful mode
    if BConfig.Listen.Graceful {
        httpsAddr := BConfig.Listen.HTTPSAddr
        app.Server.Addr = httpsAddr
        if BConfig.Listen.EnableHTTPS {
            go func() {
                ...
                if err := server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
                    logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
                    time.Sleep(100 * time.Microsecond)
                    endRunning <- true
                }
            }()
        }
        if BConfig.Listen.EnableHTTP {
            go func() {
                ...
                if err := server.ListenAndServe(); err != nil {
                    logs.Critical("ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid()))
                    time.Sleep(100 * time.Microsecond)
                    endRunning <- true
                }
            }()
        }
        <-endRunning
        return
    }
    ...
}

我们知道http.ListenAndServe逻辑如下:

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

app.Server是系统*http.Server,将Handlers传入app.Server.Handler即是构建了一个http.ListenAndServe中的server,然后在接下来调用server.ListenAndServe。至此,我们可以看到beego的启动与go中的完全一致。只是在server构建前完成了一系列的routers的存储以及响应时的匹配,这些我们在随后的文章中继续研究。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/xz_studying/article/details/89576331
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢