基于viper实现Go项目的配置
支持 :
- 读取配置文件
- 设置配置项
- 读取配置项
- 动态的读取配置文件
- 支持自定义修改读取文件的路径
下面是项目的目录结构
package conf
import (
"github.com/spf13/cast"
viperlib "github.com/spf13/viper" // 自定义包名,避免与内置 viper 实例冲突
"os"
)
// viper 库实例
var viper *viperlib.Viper
// ConfigFunc 动态加载配置信息
type ConfigFunc func() map[string]interface{}
// ConfigFuncs 先加载到此数组,loadConfig 再动态生成配置信息
var ConfigFuncs map[string]ConfigFunc
func init() {
// 1. 初始化 Viper 库
viper = viperlib.New()
// 2. 配置类型,支持 "json", "toml", "yaml", "yml", "properties",
// "props", "prop", "env", "dotenv"
viper.SetConfigType("env")
viper.AddConfigPath(".")
viper.SetEnvPrefix("appenv")
viper.AutomaticEnv()
ConfigFuncs = make(map[string]ConfigFunc)
}
func InitConfig(env string) {
// 1. 加载环境变量
loadEnv(env)
// 2. 注册配置信息
loadConfig()
}
func loadConfig() {
for name, fn := range ConfigFuncs {
viper.Set(name, fn())
}
}
func loadEnv(envSuffix string) {
envPath := ".env"
if len(envSuffix) > 0 {
filepath := ".env." + envSuffix
if _, err := os.Stat(filepath); err == nil {
// 如 .env.testing 或 .env.stage
envPath = filepath
}
}
// 加载 env
viper.SetConfigName(envPath)
if err := viper.ReadInConfig(); err != nil {
panic(err)
}
// 监控 .env 文件,变更时重新加载
viper.WatchConfig()
}
func Env(envName string, defaultValue ...interface{}) interface{} {
if len(defaultValue) > 0 {
return internalGet(envName, defaultValue[0])
}
return internalGet(envName)
}
func internalGet(path string, defaultValue ...interface{}) interface{} {
// config 或者环境变量不存在的情况
if !viper.IsSet(path) {
if len(defaultValue) > 0 {
return defaultValue[0]
}
return nil
}
return viper.Get(path)
}
// Add 新增配置项
func Add(name string, configFn ConfigFunc) {
ConfigFuncs[name] = configFn
}
func Get(path string, defaultValue ...interface{}) string {
return GetString(path, defaultValue...)
}
// GetString 获取 String 类型的配置信息
func GetString(path string, defaultValue ...interface{}) string {
return cast.ToString(internalGet(path, defaultValue...))
}
package main
import (
"demo/conf"
"flag"
"fmt"
)
func init() {
conf.Add("app",func() map[string]interface{} {
return map[string]interface{}{
"test": conf.Env("TEXT", "Hello Golang!!!"),
}
})
}
func main() {
var env string
flag.StringVar(&env, "env", "","自己配置 如--env=testing ")
flag.Parse()
conf.InitConfig(env)
res := conf.Get("app.test")
fmt.Println(res)
fmt.Println(res)
fmt.Println(res)
fmt.Println(res)
fmt.Println(res)
}
项目使用
conf.Add() //设置配置
conf.Get() //读取配置
.env
.env.test //配置文件
go run main.go --env=test //读取.env.test,默认读取.env