beego源码深入分析之初始化(一)

1.初始化流程:

1.1 包的导入过程

首先我们从整体来审视beego包的初始化过程,然后再来逐步分析每一步的详细内容。

根据go包的导入过程,我们先来分析一下beego的初始化。包的导入过程如下图:



1) 在我们自己项目的main包中首先会导入:

import "github.com/astaxie/beego",

然后go编译器开始从beego这个目录中的第一个文件admin.go开始读取,

(注:之所以说是beego目录而不是包,请参考

https://tonybai.com/2015/03/09/understanding-import-packages/这篇博文的详解)

然后发现,admin.go中又分别导入了

"github.com/astaxie/beego/grace"

"github.com/astaxie/beego/logs"

"github.com/astaxie/beego/toolbox"

"github.com/astaxie/beego/utils"

四个目录,于是编译器继续从上往下依次读取引入的目录。

首先,我们进入引入的第一个目录,grace目录中。

  在grace目录中,我们发现有四个文件,分别是:

conn.go,  grace.go, listener.go,server.go。进入这四个文件中发现,它们引入的都是go内置的包。(注:由于打算只分析beego框架的内容,所以不打算继续跟踪go内置包的引入。后期分析go源码的时候再继续追踪。)

   进入到grace目录中,根据包的导入过程规则,编译器首先会依次初始化该目录下所有文件的const常量,然后是该目录下所有文件的var变量,最后是所有文件的init()函数。由于grace目录下只有grace.go文件中有var变量和init()函数,而其他三个文件没有const常量和var变量,也没有init()函数,所以在编译运行我们自己的App时,首先会从grace目录下的grace.go中初始化变量和执行grace.init()函数。接着,按照上述规则依次加载logs目录,toolbox目录,utils目录。(注:如果在引入时,把logs和toolbox位置互换,你会发现,依次加载的目录是toolbox=>logs=>utils。由此可知,go引入目录是按照从上到下依次加载的)。


1.2 grace目录下的初始化,主要在grace.go

1.2.1 声明一些信号常量:

const (

// PreSignal is the position to add filter before signal

PreSignal = iota

   // PostSignal is the position to add filter after signal

PostSignal

   // StateInit represent the application inited

StateInit

   // StateRunning represent the application is running

StateRunning

   // StateShuttingDown represent the application is shutting down

StateShuttingDown

   // StateTerminate represent the application is killed

StateTerminate

)

1.2.2 声明Server相关的变量和http请求需要的一些参数

var (

   regLock              *sync.Mutex

   runningServers      

map[string]*Server

   runningServersOrder  []

string

socketPtrOffsetMap   map[string]uint

runningServersForked bool

// DefaultReadTimeOut is the HTTP read timeout

DefaultReadTimeOut time.Duration

// DefaultWriteTimeOut is the HTTP Write timeout

DefaultWriteTimeOut time.Duration

// DefaultMaxHeaderBytes is the Max HTTP Herder size, default is 0, no limit

DefaultMaxHeaderBytes int

// DefaultTimeout is the shutdown server's timeout. default is 60s

DefaultTimeout = 60 * time.Second

   isChild     bool

socketOrder string

hookableSignals []os.Signal

)

1.2.3 初始化1.2.2中的变量

func init() {

   flag.

BoolVar(&isChild, "graceful", false, "listen on open fd (after forking)")

   flag.

StringVar(&socketOrder, "socketorder", "", "previous initialization order - used when more than one listener was started")

   regLock = &sync.Mutex{}

   runningServers =

make(map[string]*Server)

   runningServersOrder = []

string{}

   socketPtrOffsetMap =

make(map[string]uint)

   hookableSignals = []os.Signal{

      syscall.

SIGHUP,

syscall.SIGINT,

syscall.SIGTERM,

}

}

1.3  [endif]logs目录下的初始化

1)  调用conn.go中的init(),注册网络日志logger。

2)   调用console.go中的init(),注册打印到terminal窗口的logger

3 )  调用file.go中的init(),注册将日志传输到文件中的logger

4 )  调用jianliao.go中的init(),注册jianliao日志(不知道jianliao是什么鬼东西)

5  ) 调用multile.go中的init(),注册multifilelog 日志打印器

6 )  调用slack.go中的init(),注册SLACKWriter日志打印器

7 )  调用smtp.go中的init(),注册SMTPWriter日志打印器

1.4  [endif]toolbox目录下的初始化

1)调用healthcheck.go中的init(),初始化健康检查器(HealthChecker)的容器AdminCheckList

func init() {

   AdminCheckList =

make(map[string]HealthChecker)

}

2)调用profile.go中的init(),获取当前进程的pid,并将值复制给toolbox包内变量pid

func init() {

   pid = os.

     Getpid()

}

3)调用statistics.go中的init(),初始化Statistics,主要是用来统计请求的url和method的时间

4) 调用Tasker.go中的init(),初始化Tasker


1.5  config目录下的初始化,config目录是由beego目录下config.go引入的

1)调用ini.go中的init(),注册ini格式的IniConfig

2)调用json.go中的init(),注册json格式的JsonConfig


1.6  context目录下的初始化

由于context目录下文件中没有init()方法,所以在此不做分析了

1.7  [endif]session目录下的初始化

1)调用sess_cookie.go中的init(),注册CookieProvider

2)调用sess_file.go中的init(),注册FileProvider

3 )调用sess_mem.go中的init(),注册MemProvider

4) 调用sess_utils.go中的init(),注册存储session值可以序列化的数据类型


1.8  [endif]beego目录下的初始化

1)调用admin.go中的init(),注册一些beego默认路由:qps,prof,healthcheck,listconf等

2)调用app.go中的init(),初始化一个Beego的App,BeeApp。

func init() {

// create beego application

BeeApp = NewApp()

}

在NewApp函数中主要是:1,生成了一个ControllerRegister结构体(注意这里主要是使用为了ControllerRegister中实现的ServeHttp方法),2,然后生成一个App结构体,并将1中生成的ControllerRegister和go内置的默认的http.Server作为参数赋给App。

// NewApp returns a new beego application.

func NewApp() *App {

   cr :=

NewControllerRegister()

   app := &App{Handlers: cr

, Server: &http.Server{}}


return app

}

3 )调用config.go的init(),初始化配置文件的默认值,以及读取项目中conf目录中的app.conf配置文件,并将其值赋值给配置结构体beegoAppConfig

4 )调用parser.go中的init()

5 ) 调用template.go中的init(),

1.9   项目根目录/routers目录下的初始化

1) 调用router.go中的init(),该处主要是注册路由和过滤器

1.10 项目根目录下的初始化

1) 调用main.go中的init(),

至此项目所有的初始化流程就走完了。

你可能感兴趣的:(beego源码深入分析之初始化(一))