beego的架构
beego 是基于八大独立的模块构建的,是一个高度解耦的框架。即使不使用 beego 的 HTTP 逻辑,也依旧可以使用这些独立模块。
cache:缓存逻辑;
config:解析配置文件,目前支持解析的文件格式有 ini、json、xml、yaml
context:上下文模块主要是针对 HTTP 请求中,request 和 response 的进一步封装,他包括用户的输入和输出,context 模块中提供了 Input 对象进行解析,提供了 Output 对象进行输出。
httplib 库主要用来模拟客户端发送 HTTP 请求,类似于 Curl 工具,支持 JQuery 类似的链式操作。
logs:日志模块,记录操作信息;
session 模块是用来存储客户端用户,session 模块目前只支持 cookie 方式的请求,如果客户端不支持 cookie,那么就无法使用该模块。
toolbox:这个模块中的几个功能:健康检查、性能调试、访问统计、计划任务。
执行逻辑
beego 是一个典型的 MVC 架构,它的执行逻辑如下图所示:
项目结构
M(models 目录)、V(views 目录)和 C(controllers 目录)的结构, main.go 是入口文件。
入口文件 main.go
package main
import (
_ "项目名/routers" //只引入执行了里面的 init 函数
"github.com/astaxie/beego"
)
func main() {
beego.Run()
}
beego.Run() 执行之后:
- 解析配置文件
beego 会自动解析在 conf 目录下面的配置文件 app.conf,通过修改配置文件相关的属性,我们可以定义:开启的端口,是否开启 session,应用名称等信息。 - 执行用户的 hookfunc
beego 会执行用户注册的 hookfunc,默认的已经存在了注册 mime,用户可以通过函数 AddAPPStartHook 注册自己的启动函数。 - 是否开启 session
会根据上面配置文件的分析之后判断是否开启 session,如果开启的话就初始化全局的 session。 - 是否编译模板
beego 会在启动的时候根据配置把 views 目录下的所有模板进行预编译,然后存在 map 里面,这样可以有效的提高模板运行的效率,无需进行多次编译。 - 是否开启文档功能
根据 EnableDocs 配置判断是否开启内置的文档路由功能 - 是否启动管理模块
beego 目前做了一个很酷的模块,应用内监控模块,会在 8088 端口做一个内部监听,我们可以通过这个端口查询到 QPS、CPU、内存、GC、goroutine、thread 等统计信息。 - 监听服务端口
这是最后一步也就是我们看到的访问 8080 看到的网页端口,内部其实调用了 ListenAndServe,充分利用了 goroutine 的优势
一旦 run 起来之后,我们的服务就监听在两个端口了,一个服务端口 8080 作为对外服务,另一个 8088 端口实行对内监控。
router.go
package routers
import (
"项目名/controllers"
"github.com/astaxie/beego"
)
func init() {
beego.Router("/", &controllers.MainController{})
}
路由包里面执行了路由注册 beego.Router, 这个函数的功能是映射 URL 到 controller
第一个参数是 URL (用户请求的地址),这里我们注册的是 /,也就是我们访问的不带任何参数的 URL,第二个参数是对应的 Controller,也就是我们即将把请求分发到那个控制器来执行相应的逻辑,我们可以执行类似的方式注册如下路由:
beego.Router("/user", &controllers.UserController{}) //通过访问 /user 去执行 UserController 的逻辑
正则路由
beego.Router(“/api/?:id”, &controllers.RController{}) 默认匹配
//匹配 /api/123 :id = 123 可以匹配 /api/ 这个URL
beego.Router(“/api/:id”, &controllers.RController{}) 默认匹配
//匹配 /api/123 :id = 123 不可以匹配 /api/ 这个URL
beego.Router(“/api/:id([0-9]+)“, &controllers.RController{}) 自定义正则匹配
//匹配 /api/123 :id = 123
beego.Router(“/user/:username([\w]+)“, &controllers.RController{}) 正则字符串匹配
//匹配 /user/astaxie :username = astaxie
beego.Router(“/download/*.*”, &controllers.RController{}) *匹配方式
//匹配 /download/file/api.xml :path= file/api :ext=xml
beego.Router(“/download/ceshi/*“, &controllers.RController{}) *全匹配方式
//匹配 /download/ceshi/file/api.json :splat=file/api.json
beego.Router(“/:id:int”, &controllers.RController{}) int 类型设置方式,匹配 :id为int 类型
beego.Router(“/:hi:string”, &controllers.RController{}) string 类型设置方式,匹配 :hi 为 string 类型
beego.Router(“/cms_:id([0-9]+).html”, &controllers.CmsController{}) 带有前缀的自定义正则 //匹配 :id 为正则类型。
可以在 Controller 中通过如下方式获取上面的变量:
this.Ctx.Input.Param(":id")
this.Ctx.Input.Param(":username")
this.Ctx.Input.Param(":splat")
this.Ctx.Input.Param(":path")
this.Ctx.Input.Param(":ext")
自定义方法及 RESTful 规则:
beego.Router("/",&IndexController{},"*:Index")
使用第三个参数,第三个参数就是用来设置对应 method 到函数名,定义如下
*表示任意的 method 都执行该函数(get,post,put……)
使用 httpmethod:funcname 格式来展示
多个不同的格式使用 ; 分割
多个 method 对应同一个 funcname,method 之间通过 , 来分割
beego.Router("/index", &controllers.IndexController{},"get:ShowIndex;post:Post")
beego.Router("/index", &controllers.IndexController{},"get,post:ShowIndex")
controller
package controllers
import (
"github.com/astaxie/beego"
)
//这是 Go 的嵌入方式,自动拥有了所有 beego.Controller 的方法
type MainController struct {
beego.Controller
}
func (this *MainController) Get() {}
......
beego.Controller 拥有很多方法,其中包括 Init、Prepare、Post、Get、Delete、Head 等方法。我们可以通过重写的方式来实现这些方法。
数据的使用:
this.Data[“a”] = “abc”
可以通过各种方式获取数据,然后赋值到 this.Data 中,这是一个用来存储输出数据的 map,可以赋值任意类型的值
model
model 层一般用来做数据库的操作
views
Beego模板默认支持:.tpl和.html两种后缀
beego.AddTemplateExt增加新的模板后缀
静态文件处理
beego 默认注册了 static 目录为静态处理的目录,注册样式:URL 前缀和映射的目录(在/main.go文件中beego.Run()之前加入):
StaticDir["/static"] = "static"
用户可以设置多个静态文件处理目录,例如你有多个文件下载目录 download1、download2,你可以这样映射(在 /main.go 文件中 beego.Run() 之前加入):
beego.SetStaticPath("/down1", "download1")
beego.SetStaticPath("/down2", "download2")