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

1.初始化流程:

1.1 包的導(dǎo)入過程

首先我們從整體來審視beego包的初始化過程,然后再來逐步分析每一步的詳細(xì)內(nèi)容。

根據(jù)go包的導(dǎo)入過程,我們先來分析一下beego的初始化。包的導(dǎo)入過程如下圖:



1) 在我們自己項(xiàng)目的main包中首先會(huì)導(dǎo)入:

import "github.com/astaxie/beego",

然后go編譯器開始從beego這個(gè)目錄中的第一個(gè)文件admin.go開始讀取,

(注:之所以說是beego目錄而不是包,請(qǐng)參考

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

然后發(fā)現(xiàn),admin.go中又分別導(dǎo)入了

"github.com/astaxie/beego/grace"

"github.com/astaxie/beego/logs"

"github.com/astaxie/beego/toolbox"

"github.com/astaxie/beego/utils"

四個(gè)目錄,于是編譯器繼續(xù)從上往下依次讀取引入的目錄。

首先,我們進(jìn)入引入的第一個(gè)目錄,grace目錄中。

? 在grace目錄中,我們發(fā)現(xiàn)有四個(gè)文件,分別是:

conn.go,? grace.go, listener.go,server.go。進(jìn)入這四個(gè)文件中發(fā)現(xiàn),它們引入的都是go內(nèi)置的包。(注:由于打算只分析beego框架的內(nèi)容,所以不打算繼續(xù)跟蹤go內(nèi)置包的引入。后期分析go源碼的時(shí)候再繼續(xù)追蹤。)

?? 進(jìn)入到grace目錄中,根據(jù)包的導(dǎo)入過程規(guī)則,編譯器首先會(huì)依次初始化該目錄下所有文件的const常量,然后是該目錄下所有文件的var變量,最后是所有文件的init()函數(shù)。由于grace目錄下只有g(shù)race.go文件中有var變量和init()函數(shù),而其他三個(gè)文件沒有const常量和var變量,也沒有init()函數(shù),所以在編譯運(yùn)行我們自己的App時(shí),首先會(huì)從grace目錄下的grace.go中初始化變量和執(zhí)行g(shù)race.init()函數(shù)。接著,按照上述規(guī)則依次加載logs目錄,toolbox目錄,utils目錄。(注:如果在引入時(shí),把logs和toolbox位置互換,你會(huì)發(fā)現(xiàn),依次加載的目錄是toolbox=>logs=>utils。由此可知,go引入目錄是按照從上到下依次加載的)。


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

1.2.1 聲明一些信號(hào)常量:

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相關(guān)的變量和http請(qǐng)求需要的一些參數(shù)

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) ?調(diào)用conn.go中的init(),注冊網(wǎng)絡(luò)日志logger。

2) ? 調(diào)用console.go中的init(),注冊打印到terminal窗口的logger

3 ) ?調(diào)用file.go中的init(),注冊將日志傳輸?shù)轿募械膌ogger

4 ) ?調(diào)用jianliao.go中的init(),注冊jianliao日志(不知道jianliao是什么鬼東西)

5 ?) 調(diào)用multile.go中的init(),注冊multifilelog 日志打印器

6 ) ?調(diào)用slack.go中的init(),注冊SLACKWriter日志打印器

7 ) ?調(diào)用smtp.go中的init(),注冊SMTPWriter日志打印器

1.4??[endif]toolbox目錄下的初始化

1)調(diào)用healthcheck.go中的init(),初始化健康檢查器(HealthChecker)的容器AdminCheckList

func init() {

?? AdminCheckList =

make(map[string]HealthChecker)

}

2)調(diào)用profile.go中的init(),獲取當(dāng)前進(jìn)程的pid,并將值復(fù)制給toolbox包內(nèi)變量pid

func init() {

?? pid = os.

? ? ?Getpid()

}

3)調(diào)用statistics.go中的init(),初始化Statistics,主要是用來統(tǒng)計(jì)請(qǐng)求的url和method的時(shí)間

4) 調(diào)用Tasker.go中的init(),初始化Tasker


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

1)調(diào)用ini.go中的init(),注冊ini格式的IniConfig

2)調(diào)用json.go中的init(),注冊json格式的JsonConfig


1.6 ?context目錄下的初始化

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

1.7??[endif]session目錄下的初始化

1)調(diào)用sess_cookie.go中的init(),注冊CookieProvider

2)調(diào)用sess_file.go中的init(),注冊FileProvider

3 )調(diào)用sess_mem.go中的init(),注冊MemProvider

4) 調(diào)用sess_utils.go中的init(),注冊存儲(chǔ)session值可以序列化的數(shù)據(jù)類型


1.8??[endif]beego目錄下的初始化

1)調(diào)用admin.go中的init(),注冊一些beego默認(rèn)路由:qps,prof,healthcheck,listconf等

2)調(diào)用app.go中的init(),初始化一個(gè)Beego的App,BeeApp。

func init() {

// create beego application

BeeApp = NewApp()

}

在NewApp函數(shù)中主要是:1,生成了一個(gè)ControllerRegister結(jié)構(gòu)體(注意這里主要是使用為了ControllerRegister中實(shí)現(xiàn)的ServeHttp方法),2,然后生成一個(gè)App結(jié)構(gòu)體,并將1中生成的ControllerRegister和go內(nèi)置的默認(rèn)的http.Server作為參數(shù)賦給App。

// NewApp returns a new beego application.

func NewApp() *App {

?? cr :=

NewControllerRegister()

?? app := &App{Handlers: cr

, Server: &http.Server{}}


return app

}

3 )調(diào)用config.go的init(),初始化配置文件的默認(rèn)值,以及讀取項(xiàng)目中conf目錄中的app.conf配置文件,并將其值賦值給配置結(jié)構(gòu)體beegoAppConfig

4 )調(diào)用parser.go中的init()

5 ) 調(diào)用template.go中的init(),

1.9 ? 項(xiàng)目根目錄/routers目錄下的初始化

1) 調(diào)用router.go中的init(),該處主要是注冊路由和過濾器

1.10 項(xiàng)目根目錄下的初始化

1) 調(diào)用main.go中的init(),

至此項(xiàng)目所有的初始化流程就走完了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容