写在前面
beego 是一个快速开发 Go 应用的 HTTP 框架,他可以用来快速开发 API、Web 及后端服务等各种应用,是一个 RESTful 的框架,主要设计灵感来源于 tornado、sinatra 和 flask 这三个框架,但是结合了 Go 本身的一些特性(interface、struct 嵌入等)而设计的一个框架;MVC架构如下:具体内容会在后面部分给出,先从Config入口
关于config
首先要搞清楚一点Config在整个beego框架承担的任务:提供Ini、yaml、xml、json、env等方式参数配置,并提供了不同config方式的接口。
- config构成
config对应beego项目的config包构成涉及了env(env配置)、xml(xml配置)、yaml(yaml配置)、ini(ini配置,也是默认方式)、json(json配置方式)、fake(伪造配置类)、config(配置功能接口)
2.剖析
- 2.1 Configer接口
该接口定义如何从配置原始数据获取或设置内容相关规范行为,而完成最终的操作是由具体实现Configer接口的具体Configer类来完成的。- IniConfigContainer:ini配置类
- JSONConfigContainer:json配置类
- ConfigContainer:yaml配置类
- ConfigContainer:xml配置类
- 关于env是没有配置类, 实际上env只需要get、set操作即可: env-key:env-value形式
前面四种配置类采用的类似database/sql模式,定义两部分接口配置文件的Parse(见Config接口部分)和Operation,其具体实现配置类则根据自己的实际情况实现对应的接口(后面会有专门的源码来进行说明)
- 2.2 Config接口
该接口定义对应的配置文件的Parse操作,主要通过解析配置文件获取其原始数据内容绑定到Configer,可进行Configer里面的get、set等操作 - 2.3 Register方法
该方法主要完成将不同配置类型及其具体配置实现类进行注册,能够在本地进行缓存,便于使用。通过map[string]Config来存放。 - 2.4 NewConfig方法和NewConfigData方法
新建Config:第一个根据filepath来新建,第二种直接根据文件内容来新建;其中第一个参数adapterName包括:ini/json/xml/yaml - 2.5 源码
- 接口定义
配置文件操作
- 接口定义
type Configer interface {
// 添加
Set(key, val string) error //support section::key type in given key when using ini type.
//support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
// 获取
String(key string) string
// 可能会存在某个key有多个值
Strings(key string) []string //get string slice
// 根据value具体的类型进行转换
Int(key string) (int, error)
Int64(key string) (int64, error)
Bool(key string) (bool, error)
Float(key string) (float64, error)
// support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
DefaultString(key string, defaultVal string) string
DefaultStrings(key string, defaultVal []string) []string //get string slice
DefaultInt(key string, defaultVal int) int
DefaultInt64(key string, defaultVal int64) int64
DefaultBool(key string, defaultVal bool) bool
DefaultFloat(key string, defaultVal float64) float64
DIY(key string) (interface{}, error)
GetSection(section string) (map[string]string, error)
SaveConfigFile(filename string) error
}
解析配置文件
type Config interface {
Parse(key string) (Configer, error)
ParseData(data []byte) (Configer, error)
}
注册配置解析类
// 对应的Config实现类不能被注入两次或者adapter不能为nil 否则都会触发panic
func Register(name string, adapter Config) {
if adapter == nil {
panic("config: Register adapter is nil")
}
if _, ok := adapters[name]; ok {
panic("config: Register called twice for adapter " + name)
}
adapters[name] = adapter
}
创建Config
// adapter名字和对应的配置文件 创建对应的Configer
func NewConfig(adapterName, filename string) (Configer, error) {
adapter, ok := adapters[adapterName]
if !ok {
return nil, fmt.Errorf("config: unknown adaptername %q (forgotten import?)", adapterName)
}
return adapter.Parse(filename)
}
// 根据配置文件的内容及对应adapter来创建Configer
func NewConfigData(adapterName string, data []byte) (Configer, error) {
adapter, ok := adapters[adapterName]
if !ok {
return nil, fmt.Errorf("config: unknown adaptername %q (forgotten import?)", adapterName)
}
return adapter.ParseData(data)
}
获取环境变量的值
前提:
// 若是value的value则返回对应的环境变量的值.//若是环境变量为空或不存在则输出默认值//value接收的格式:"{value} 则返回对应的环境变量的值. // 若是环境变量为空或不存在 则输出默认值 // value接收的格式:"va