beego源码

Beego源码解析—配置项初始化流程

作者:admin 2017-08-22 我要评论( )

beego是一个快速开发 Go应用的 HTTP框架,他可以用来快速开发 API、Web以及后端服务等各种应用,是一个 RESTful框架。 想了解更多关于 Beego的介绍,可以看 官方文...

简介

beego是一个快速开发 Go应用的 HTTP框架,他可以用来快速开发 API、Web以及后端服务等各种应用,是一个 RESTful框架。
 想了解更多关于 Beego的介绍,可以看 官方文档
 本文及以后的文章都采用 stable v1.6.1版本
 Beego项目Github地址

动力

最近在看 Beego的源码,我选择 Beego一方面是因为我对 Go语言很感兴趣,另一方面在 GoWeb方面 Beego也做的十分出色。模块化的设计、完善的文档和社区、强大的功能都是我对于 Beego下手的推动力。
对于一个解析项目的开始,我都想从配置来下手。所以这篇文章也是主要介绍了 Beego在启动过程中配置项的初始化过程。这也是关于 Beego的第一篇文章,日后我们慢慢补坑的。

关于 Beego源码的注释可以见我的 Github 我会很努力的慢慢完善它的 :D

beego配置项的解析

在开始之前先让我们用 bee工具创建一个 Beego的应用。  项目的结构大概是这样的

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

myproject

|—conf

|—app.conf

|—controllers

|—default.go

|—main.go

|—modules

|—routers

|—router.go

|—static

|—css

|—img

|—js

|—tests

|—default_test.go

|—views

|—index.tpl

 

配置文件

可以看到 那个conf/app.conf就是项目的默认配置文件了
在配置文件中的配置项都是采用 键值对 的方式,即 key = value

我们看下 beego中对于关于配置的一些文件
beego目前支持 INI、XML、JSON、YAML格式的配置文件解析,默认是 INI格式的解析
beego/config这个包内放的就是不同解析器的文件
beego/config.go这个文件就是用来初始化配置项的文件

程序中的配置项

在 beego的启动过程中,有两个变量对配置项的初始化很重要,它们都在 beego/config.go:106被声明

1

2

3

4

5

6

var (

BConfig *Config

AppConfig *beegoAppConfig

 

...配置文件的路径等变量

)

 

BConfig是程序在整个运行过程中都需要用的,而 AppConfig是用来解析配置项的接口,所以整个配置项的解析过程来说就是 使用 AppConfig去完成 BConfig的初始化
(关于 Config这个结构体的定义可以参考 beego/config.go:50行开始的 ListenWebConfigSessionConfigLogConfig这四个结构体,注意这里的 Config保存的是程序运行是已经解析好的配置,而与下文提到的 beego/config/Config接口无关)

关于 beegoAppConfig结构体

让我们继续进入 beegoAppConfig结构体,在 beego/config.go:340可以看到定义

1

2

3

type beegoAppConfig struct{

innerConfig config.Configer

}

 

明白了吧,其实它就是 config包中 Configer接口的封装.所以在 beego/config.go文件后面部分都是在调用这个接口从而实现了 beegoAppConfig的很多方法
关于 config.Configer接口我们可以在 config/config.go:50找到,它定义了16种在解析配置项中可能用到的方法
不过正在看源码的同学可能会发现在 Configer接口下还有个 Config接口,那么它又是干什么的呢?

1

2

3

4

type Config interface{

Parse(key string)(Configer,error)

ParseData(data []byte)(Configer,error)

}

 

看下它的接口定义我们就能猜到,它是为了给我们创建一个 Configer实例的.而 Parse()和 ParseData()两个函数在不同的配置器实现里都有不同的实现,但他们的目的也就只有创建实例了。

保存配置器的 map

看到这里需要打断下,因为又有一个非常重要的变量需要我们认识
在 beego/config/config.go:85行有这样一行

1

var adapters = make(map[strng]Config)

 

为什么说这个变量很重要呢,看看参数便知。map的 key是 string类型,也就是我们对应配置器的名称(“ini”、”xml”等)
而第二个就是我们刚才定义了 Parse()和ParseData()方法的 Config接口,在同文件的91行可以看到一个叫 Register的函数。在不同的配置器文件的init()函数中,配置器都会通过 Register函数向 adapters变量进行注册(比如打开 beego/config/json.go拖到文件末尾就可以看到)
也就是说在 beego/config/包中所有源文件的 init()函数执行完时, adapters就已经保存了所有配置器了

这样在 beego/config.go文件中使用时只需要传入配置器的名字,就能获得对应的 Config接口方法,调用方法后就能获得实现了 Configer接口所有方法的实例了!
那么接下来就比较简单了,不同的配置器只需要在自己文件中实现 Configer接口的所有方法就能成功的解析文件了,这里只需要根据不同格式进行配置项的处理即可

BConfig的初始化

通过这样自顶向下的分析,大家应该能够对这几个接口和函数之间的关系有了大概的思路了吧,既然我们现在已经知道如何得到 beegoAppConfig这样实现了16种解析方法的实例,那么接下来也就是通过这个实例给我们需要的BConfig变量赋值了。
首先在 beego/config.go文件的 init()函数中我们可以看到了一大片关于给 BConfig赋默认值的代码,并且在 init()函数的最后 使用 appConfigPath(保存配置文件路径的string类型变量 beego/config.go:117)检查配置文件是否存在,然后调用 parseConfig()函数开始配置的解析过程
在 parseConfig()函数中首先是调用了本包内的 newAppConfig()函数给 AppConfig初始化, 然后就可以看到使用了 AppConfig中实现的Congiger接口的方法给BConfig赋了很多值并且在函数末尾初始化了log
因为给 BConfig初始化的代码在 init()函数中,所以在 beego.App.Run()方法中并不能看到初始化配置项的代码。也就是说在 Run()函数运行前,配置就已经赋值完成了 :D

 

}

转载请注明出处。

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 使用 beego 搭建 web 应用

    2017-08-24

  • Beego源码解析(三)-HTTP请求处理流程

    2017-08-23

  • Beego源码解析(二)-路由机制

    2017-08-23

网友点评