原文链接:
Beego源码解析(四)-Hook函数
在前三篇文章中,介绍了 Beego作为 Web框架最基本的配置解析、路由机制、请求处理三个流程.现在我们应该就已经对 Beego很是了解
后面的文章就让我们重新头开始看看除了这三个基本功能外,Beego还做了什么其他的事情吧~
这篇文章会介绍在 Beego启动时调用的6个 hook函数
关于 Beego源码的注释可以看我的Github
回到最开始的 beego.Run()函数(beego.go:53)。可以看到在函数的第一行就有一个
initBeforeHTTPRun()
而且这个函数定义也就在下面紧挨着
func initBeforeHTTPRun() {
//讲每个函数添加到 hooks中,并且逐个调用
AddAPPStartHook(registerMime)
AddAPPStartHook(registerDefaultErrorHandler)
AddAPPStartHook(registerSession)
AddAPPStartHook(registerDocs)
AddAPPStartHook(registerTemplate)
AddAPPStartHook(registerAdmin)
for _, hk := range hooks {
if err := hk(); err != nil {
panic(err)
}
}
}
这里看到有个 hooks变量,它在本文件的37行被定义
type hookfunc func() error
var (
hooks = make([]hookfunc,0)
)
func AddAppStartHook(hf hookfunc){
hooks = append(hooks,hf)
}
这样就很清楚了,hooks是一个保存函数的切片,而在 initBeforeHTTPRun()中通过调用 AddAppStartHook函数将对应的函数添加进 hooks中
在函数的最后也可以看到是通过一个 range调用保存在 hooks里的所有函数
那么这添加进去的6个函数又是干么的呢?
在 hooks.go中可以看到他们的身影
registerMime
这个函数比较短,它只是使用了标准库的 mime包,向其中添加关联,这个 mimemaps不出所料也是一个 map[string][string]类型的map,其中包含了所有对应的关联信息.想要了解的可以查看 mime.go这个文件
func registerMine() error{
for k,v:=range mimemaps{
mime.AddExtensionType(k,v)
}
return nil
}
registerDefaultErrorHandler
这个函数也同样很好理解,它定义了不同出错码对应的函数,然后用 ErrorHandler函数注册进一个叫 ErrorMaps的 map[string]*errInfo类型的map中,并在以后用于出错处理
关于出错处理的这几个函数可以参考 error.go文件,并不是很复杂就不多说了
func registerDefaultErrorHandler() error {
m := map[string]func(http.ResponseWriter, *http.Request){
"401": unauthorized,
"402": paymentRequired,
"403": forbidden,
"404": notFound,
"405": methodNotAllowed,
"500": internalServerError,
"501": notImplemented,
"502": badGateway,
"503": serviceUnavailable,
"504": gatewayTimeout,
}
for e, h := range m {
if _, ok := ErrorMaps[e]; !ok {
ErrorHandler(e, h)
}
}
return nil
}
registerSession
这个函数看名字就知道是关于 Session的,它会通过配置文件判断是否开启了 Session,并且获得配置
再然后就通过调用 Session包里的 NewManger函数获得一个 Session管理器的实例,并且使用 goroutine开始一个Gc()来管理 Session
这里的 GlobalSessions在 config.go:114行被声明,作用于全局
关于 Seesion管理器可能(额=.=)以后会更新说明
func registerSession() error {
// BConfig(位于 config.go内的全局变量)
if BConfig.WebConfig.Session.SessionOn {
var err error
sessionConfig := AppConfig.String("sessionConfig")
if sessionConfig == "" {
// 启用默认的 Session配置
conf := map[string]interface{}{
"cookieName": BConfig.WebConfig.Session.SessionName,
"gclifetime": BConfig.WebConfig.Session.SessionGCMaxLifetime,
"providerConfig": filepath.ToSlash(BConfig.WebConfig.Session.SessionProviderConfig),
"secure": BConfig.Listen.EnableHTTPS,
"enableSetCookie": BConfig.WebConfig.Session.SessionAutoSetCookie,
"domain": BConfig.WebConfig.Session.SessionDomain,
"cookieLifeTime": BConfig.WebConfig.Session.SessionCookieLifeTime,
}
confBytes, err := json.Marshal(conf)
if err != nil {
return err
}
sessionConfig = string(confBytes)
}
if GlobalSessions, err = session.NewManager(BConfig.WebConfig.Session.SessionProvider, sessionConfig); err != nil {
return err
}
//开启一个goroutine来处理session的回收,定义于 session.session.go:227
go GlobalSessions.GC()
}
return nil
}
registerTemplate
构建模板的函数,这样在以后使用模板可以更加方便
关于模板的函数可以看 template.go文件
以后可能(额=.=)会有关于模板的介绍…
func registerTemplate() error {
if err := BuildTemplate(BConfig.WebConfig.ViewsPath); err != nil {
if BConfig.RunMode == DEV {
Warn(err)
}
return err
}
return nil
}
registerDocs
Beego的自动化文档是否开始,可以看出这里就只是注册了两个路由
关于自动化文档的使用可以看官方文档
func registerDocs() error {
if BConfig.WebConfig.EnableDocs {
Get("/docs", serverDocs)
Get("/docs/*", serverDocs)
}
return nil
}
registerAdmin
在 Beego的文档中都知道有一个叫进程内监控的功能,如果配置文件开启了,那么这里就会用 goroutine开启一个监控
相关的使用方法可以参考官方文档
也可以参考 beego/admin.go文件
func registerAdmin() error {
if BConfig.Listen.EnableAdmin {
go beeAdminApp.Run()
}
return nil
}
这篇文章比较短,因为这几个函数的逻辑都比较简单。分别处理哪些事情看名字都比较容易知道
想要更深入了解的可以查看相关的源文件
如果错误,希望指正:D