千家信息网

golang中beego的示例分析

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要介绍golang中beego的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1.http.HandleFunc将pattern及我们自定义的handler存
千家信息网最后更新 2026年11月02日golang中beego的示例分析

这篇文章主要介绍golang中beego的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

1.http.HandleFunc将pattern及我们自定义的handler存储在DefaultServeMux的一个map中。

2.当http.ListenAndServe的handler为nil时,系统会从DefaultServeMux存储信息的map中匹配pattern获取对应的handler,进而处连接请求。

如果用更简单的话来总结以上两条,就是:路由的存储与匹配

beego作为一个基于golang之上的框架(此处只讨论核心http及路由部分的处理),必然脱离不了语言底层的支持。因此,我们可以大胆猜测,beego的路由处理主要是在HandleFunc的封装上,即如何更好的封装HandlerFunc且便于使用,这应该也是beego支持多种路由方式的特点了。

一、beego.Run

我们先从源码来验证一条简单的猜测,beego基于http.ListenAndServe来处理网络请求(本次仅针对http协议的处理进行分析,https协议类似)。

beego.Run()->BeeApp.Run()

// 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()

}

可以很明显的看出beego最终和http.ListenAndServe调用的接口是一样的。(此处只对http部分进行分析,https协议也是通用的只是调用的接口是ListenAndServeTLS)

二、Router

1.支持的路由方式

根据官网的描述,beego支持以下路由方式:

基础路由

beego.Get

beego.Post

…

自定义的 handler 实现

s := rpc.NewServer()

s.RegisterCodec(json.NewCodec(), "application/json")

s.RegisterService(new(HelloService), "")

beego.Handler("/rpc", s)

固定路由&正则路由&自定义方法

// 固定路由

beego.Router("/", &controllers.MainController{})

beego.Router("/admin", &admin.UserController{})

// 正则路由

beego.Router("/api/?:id", &controllers.RController{})

beego.Router("/cms_:id([0-9]+).html", &controllers.CmsController{}))

// 指定方法

beego.Router("/api/list",&RestController{},"*:ListFood")

beego.Router("/api/create",&RestController{},"post:CreateFood")

自动匹配路由

beego.AutoRouter(&controllers.ObjectController{})

-注解路由

// @router /all/:key [get]

func (this *CMSController) AllBlock() {

}

beego.Include(&CMSController{})

namespace

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)

NSNamespace/NewNamespace内部的部分存储路由时,只处理了自身的路由,总的路由还需要在NSNamespace/NewNamespace进行添加prefix,最终存储在BeeApp.Handlers.routers.

数据传输在此进行:

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")

在此,我们研究下几个主要入口作为示例来分析源码。

2.具体路由方式的分析

在初探中我们只做简单的功能分析,具体的分析我们在后续的文章中加以补充。

(1)beego.Get

beego.Get->BeeApp.Handlers.Get->p.AddMethod->p.addToRouter

其中p即BeeApp.Handlers,因此这一连串的操作主要是将router信息存入BeeApp.Handlers中。

(2)beego.Router

beego.Router->BeeApp.Handlers.Add->p.addWithMethodParams->p.addToRouter

与(1)同理

(3)beego.AutoRouter

beego.AutoRouter->BeeApp.Handlers.AddAuto->p.AddAutoPrefix->p.addToRouter

与(1)同理

(4)beego.Include

beego.Include->BeeApp.Handlers.Include->p.addWithMethodParams->p.addToRouter

与(1)同理

(5)beego.AddNamespace

beego.AddNamespace->BeeApp.Handlers.routers[k]

直接将namespace.handlers.routers中的添加前缀后存入BeeApp.Handlers.routers中。

AddNamespace、NSNamespace及其内部的一系列NSNamespace方法集最终依然调用n.handlers的方法集中,然后经过AddNamespace,保存至BeeApp.Handlers中

三、ServeHTTP

既然处理请求时,经过了http.ListenAndServe,根据我们对ListenAndServe的分析,最终请求会交由server.Handler的ServeHTTP来处理。beego中的Handler即为BeeApp.Handlers,其类型是ControllerRegister,也就是说请求最终交由ControllerRegister的ServeHTTP实现来处理。此处我们也是只谈下处理过程,具体的细节我们在之后的分析文章内细谈。

三、总结

我们分别从两个入口beego.Run、router两个入口的使用,可以看到beego处理的逻辑基本上和golang底层http.ListenAndServe、http.HandleFunc的原理一致,只是有更高层次的封装,以及更便利的路由声明及处理。在后续的文章中我们会对beego的处理作进一步的分析。

最后,我们可以做下几点简单的总结:

(1)routers package主要是生成路由及处理的相关信息,并保存至BeeApp.Handler中,

(2)beego.Run则是带着BeeApp.Handler的启动http的服务,

(3)接收请求后,由BeeApp.Handler的ServeHTTP进行处理,作出对应响应。

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

1

接下来我们一步步看下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的存储以及响应时的匹配

以上是"golang中beego的示例分析"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

路由 处理 分析 存储 方式 入口 方法 部分 支持 示例 两个 信息 只是 文章 源码 逻辑 封装 一致 接下来 代码 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技图片 科技互联网技术 艾特科技互联网 百单互联网科技有限公司 互联网科技视频素材 四个字互联网科技公司取名 银川新华互联网科技学校地址 互联网汽车科技小镇 须眉科技是互联网公司吗 湖北码尼互联网科技有限公司电话 深圳市罗太互联网科技有限公司 为客找房互联网科技公司怎么样 梅州GM互联网络科技有限公司 张召忠谈中国互联网科技 厦门江牛科技互联网 2021世界互联网领先科技成果发布 互联网科技手机排行榜 银川新华互联网科技学校是国营吗 互联网科技创业有什么好项目 利用互联网等科技手段 互联网中国科技 北京互联网科技有限公司 九亚互联网科技 哈尔滨秒房互联网科技有限公司 金融科技与互联网金融相同和不同 如何创新互联网科技 美国互联网科技实力 黑科技 体验场景 互联网大会 易企秀互联网科技是做什么的 瑞安市蟠桃会互联网科技有限公司
0