golang 配置文件解析神器--viper
项目地址:https://github.com/spf13/viper
安装方式:go get github.com/spf13/viper
简介
viper是一个十分强大的配置文件解析工具,具有以下特点
- 设置默认值
- 支持的文件包括JSON, TOML, YAML, HCL, envfile 和 Java properties 配置文件
- 实时监听和重新读取配置文件
- 从环境变量中读取
- 从远程配置系统(etcd或Consul)中读取,并监听更改
- 从命令行读取
- 从缓冲读取
- 设置显示值
另外需要注意的是,viper对配置中的key
是大小写不敏感的
下面我以YAML格式的配置文件为例,介绍viper的用法,其他跟多的用法请见官网
示例配置文件
一个好的项目应该把配置文件分成两份,一份存放不敏感信息(比如项目运行端口),一份存放敏感信息(比如数据库密码),下面两个配置文件用作举例
public config config/config/config.yaml
TimeStamp: "2018-07-16 10:23:19"
Username: "horika"
BasicInfo:
RealName: "Harry"
Age: "18"
Language:
- "Golang"
- "Python"
- "C++"
Married: false
Hobby:
Sport:
- "Lure"
- "pingpong"
Music:
- "Bohemian Rhapsody"
LuckyNumber: 22
secret config config/secret/secret.yaml
redis:
admin:
addr: "127.0.0.1:6379"
password: ""
db: 0
mysql:
driver: "mysql"
uri:
"root:123456@tcp(localhost:3306)/user?charset=utf8&parseTime=True&loc=Local&multiStatements=true"
jwt:
secret: "horika@^-^@kainhuck"
告诉viper你要解析的配置文件是什么
示例代码
var config *viper.Viper
// Init 初始化配置文件解析
func Init(){
config = viper.New()
// 设置 public 配置文件名
config.SetConfigName("config")
// 设置 public 配置文件类型
config.SetConfigType("yaml")
// 设置配置文件存放的目录
config.AddConfigPath("./config/config")
// 读取该配置文件
config.ReadInConfig()
// 解析 secret config
config.SetConfigName("secret")
config.SetConfigType("yaml")
config.AddConfigPath("./config/secret")
config.MergeInConfig()
}
说明
- SetConfigName 指定配置文件名,不需要加后缀
- SetConfigType 指定配置文件类型,可以省略,viper会自动识别
- AddConfigPath 添加配置文件所在目录,可以多个,告诉viper区哪里寻找配置文件
- ReadInConfig 从前面告知的配置中加载配置文件
- MergeInConfig 从前面告知的配置中加载配置文件并合并到之前
上面演示的只是一种读取方式,viper还有其他的读取方式
var config *viper.Viper
// Init 初始化配置文件解析
func Init(){
config = viper.New()
// 设置 public 配置文件名
config.SetConfigFile("./config/config/config.yaml")
// 读取该配置文件
config.ReadInConfig()
// 解析 secret config
config.SetConfigFile("./config/secret/secret.yaml")
config.MergeInConfig()
}
说明
- SetConfigFile 指定配置文件的全路径
从IO流中读取配置文件
var config *viper.Viper
// Init 初始化配置文件解析
func Init() {
config = viper.New()
f, _ := os.Open("./config/config/config.yaml")
defer f.Close()
config.SetConfigType("yaml")
config.ReadConfig(f)
s, _ := os.Open("./config/secret/secret.yaml")
defer s.Close()
config.SetConfigType("yaml")
config.MergeConfig(s)
}
说明
- ReadConfig 读取io流,注意和ReadInConfig区分
- SetConfigType 从流中读取需要指定文件类型
读取配置文件
viper读取配置文件就是各种Get
- Get 自动判断类型
- GetTime 获取时间类型
- GetString 获取字符串类型
- GetBool 获取bool类型
- GetInt 获取int类型
- GetStringMap 获取map类型
- ...
示例
fmt.Println(config.Get("username"))
fmt.Println(config.Get("mysql"))
fmt.Println(config.GetTime("timestamp"))
序列化
viper作为一个优秀的配置文件解析工具,他支持将配置信息序列化为结构体对象
package main
import (
"fmt"
"github.com/spf13/viper"
)
var config *viper.Viper
var AllConfig TotalConfig
// Init 初始化配置文件解析
func Init() {
config = viper.New()
config.SetConfigFile("./config/config/config.yaml")
config.ReadInConfig()
config.SetConfigFile("./config/secret/secret.yaml")
config.MergeInConfig()
config.Unmarshal(&AllConfig)
}
type basicinfo struct {
RealName string
Age int
Language []string
Married bool
}
type hobby struct {
Sport []string
Music []string
LuckyNumber int
}
type admin struct {
Addr string
paswsword string
db int
}
type redis struct {
Admin admin
}
type mysql struct {
Driver string
Uri string
}
type jwt struct {
Secret string
}
type TotalConfig struct {
TimeStamp string
Username string
BasicInfo basicinfo
Hobby hobby
Redis redis
Mysql mysql
Jwt jwt
}
func main() {
Init()
fmt.Println(AllConfig.BasicInfo.Married)
fmt.Println(AllConfig.Jwt.Secret)
}