美文网首页
beego学习-生命周期

beego学习-生命周期

作者: 噫那里有条咸鱼 | 来源:发表于2020-12-07 17:27 被阅读0次

    beego是一个组件化(模块化)的web框架,依赖于个部分的协同工作处理request,类似于php的laravel / symfony

    beego组件示意图


    beego执行逻辑

    一个典型的web应用,入口监听到请求,然后通过路由功能映射到控制器,执行业务逻辑,最后输出响应,执行流程中通过AOP的思想在不干涉业务逻辑的同时,接入日志、缓存等。


    源码分析

    • beego的生命周期的几个关键节点

    启动应用(app) -> 初始化上下文(context) -> 路由(route) -> 过滤器(filter, 等同于其他框架的Middleware) -> 控制器(Controller) -> 业务逻辑交互 -> 响应(response)

    • 框架入口main.go

    主要是调用beego.Run()启动框架:

    func main() {
        ......
        beego.Run()
    }
    
    

    beego.Run方法,启动框架:

    //====== github.com/astaxie/beego/beego.go ======
    func Run(params ...string) {
        //在处理http请求前完成一些初始化
        initBeforeHTTPRun()
    
        if len(params) > 0 && params[0] != "" {
            strs := strings.Split(params[0], ":")
            if len(strs) > 0 && strs[0] != "" {
                //处理IP地址
                BConfig.Listen.HTTPAddr = strs[0]
            }
            if len(strs) > 1 && strs[1] != "" {
                //处理端口
                BConfig.Listen.HTTPPort, _ = strconv.Atoi(strs[1])
            }
            //设置当前域名信息
            BConfig.Listen.Domains = params
        }
        //启动应用
        BeeApp.Run()
    }
    

    initBeforeHTTPRun方法,请求开始前的初始化:

    //====== github.com/astaxie/beego/beego.go ======
    func initBeforeHTTPRun() {
        //初始化 hook
        AddAPPStartHook(
            registerMime,
            registerDefaultErrorHandler,
            registerSession,
            registerTemplate,
            registerAdmin,
            registerGzip,
        )
        ......
    }
    

    回到BeeApp.Run()方法,启动应用:

    //====== github.com/astaxie/beego/app.go ======
    func (app *App) Run(mws ...MiddleWare) {
        addr := BConfig.Listen.HTTPAddr
        ......
        //注册cgi服务
        if BConfig.Listen.EnableFcgi {......}
        
        //注册http server
        app.Server.Handler = app.Handlers
        for i := len(mws) - 1; i >= 0; i-- {
            if mws[i] == nil {
                continue
            }
            app.Server.Handler = mws[i](app.Server.Handler)
        }
        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")
    
        //注册grace模块
        if BConfig.Listen.Graceful {......}
    
        //启用http配置
        if BConfig.Listen.EnableHTTP {
                go func() {
                    server := grace.NewServer(addr, app.Server.Handler)
                    server.Server.ReadTimeout = app.Server.ReadTimeout
                    server.Server.WriteTimeout = app.Server.WriteTimeout
                    //默认监听tcp4
                    if BConfig.Listen.ListenTCP4 {
                        server.Network = "tcp4"
                    }
                    //启动http服务
                    if err := server.ListenAndServe(); err != nil {
                        logs.Critical("ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid()))
                        time.Sleep(100 * time.Microsecond)
                    }
                    //给endRunning管道发送执行成功消息
                    endRunning <- true
                }()
            }
            //endRunning管道阻塞到启动成功
            <-endRunning
    }
    

    BeeApp.Run()中将http请求注册为了app.Handlers,让我们来看看app.Handlers

    //====== github.com/astaxie/beego/app.go ======
    import (
        ......
        "net"
        "net/http"
        "net/http/fcgi"
        ......
    )
    
    type App struct {
        //声明了处理器,指向控制器的注册
        Handlers *ControllerRegister
        //声明了http服务,使用net/http包
        Server   *http.Server
    }
    
    func init() {
        BeeApp = NewApp()
    }
    
    func NewApp() *App {
        //完成控制器的注册
        cr := NewControllerRegister()
        //创建应用实例
        app := &App{Handlers: cr, Server: &http.Server{}}
        return app
    }
    

    进入到NewControllerRegister

    //====== github.com/astaxie/beego/router.go ======
    
    //ControllerRegister结构体包含了路由注册规则,控制器处理器,过滤器(中间件)
    type ControllerRegister struct {
        routers      map[string]*Tree
        enablePolicy bool
        policies     map[string]*Tree
        enableFilter bool
        filters      [FinishRouter + 1][]*FilterRouter
        pool         sync.Pool
    }
    
    func NewControllerRegister() *ControllerRegister {
        return &ControllerRegister{
            //创建新的路由树、策略树、上下文同步池
            routers:  make(map[string]*Tree),
            policies: make(map[string]*Tree),
            pool: sync.Pool{
                New: func() interface{} {
                    return beecontext.NewContext()
                },
            },
        }
    }
    

    至此路由注册完成


    生命周期流程图

    相关文章

      网友评论

          本文标题:beego学习-生命周期

          本文链接:https://www.haomeiwen.com/subject/fdytgktx.html