前言

对于现代应用程序,尤其大中型的项目来说,在程序启动和运行时,往往需要传入很多参数来控制程序的行为,这些参数可以通过以下几种方式传递给程序:

  • 命令行参数
  • 环境变量
  • 配置文件

显然,对于Go项目而言,单个去读取命令行、环境变量、配置文件并不难,但一个个读取却是很麻烦,有没有一个第三方库可以帮我们一次性读取上面几种数据源的配置呢?有的,就是使用 viper 库,viper支持读取不同数据源和不同格式的配置文件,是Go项目读取配置的神器。

viper配置优先级

viper支持从多个数据源读取配置值,因此当同一个配置key在多个数据源有值时,viper读取的优先级如下(从高到低):

  • 显示使用Set函数设置值
  • flag:命令行参数
  • env:环境变量
  • config:配置文件
  • key/value store:key/value存储系统,如(etcd)
  • default:默认值

#从Viper中获取值

读取配置文件

demo环境有两个配置文件config.yaml和config.json,其中config.yaml配置的是mysql,而config.json配置的是gin。demo环境的目录结构如下:

viper - 图1

viper支持JSON、TOML、YAML、HCL、envfile和Java properties格式的配置文件。

第一种方式:直接指定文件路径

viper.SetConfigType("yaml")
// 注意:如果使用相对路径,则是以main.go为当前位置与配置文件之间的路径
viper.SetConfigFile("./connect/config.yaml")
err := viper.ReadInConfig() // 查找并读取配置文件
if err != nil {             // 处理读取配置文件的错误
    panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
mysql := viper.Get("mysql")
fmt.Println(mysql)

SetConfigType()指定了viper读去配置文件的类型
SetConfigFile()指定配置文件路径。
上面的例子中指定读取yaml文件,则json配置文件就不会被读取,反之亦然。

但是,如果没有指定配置文件的类型,指定了两次配置文件的路径(想把.json文件和.yaml文件都读取),那么结果是怎样的呢?其实SetConfigFile方法中的路径有被覆盖的特点,也就是只能指定一个路径。如果指定了多个,谁在下面谁就会生效。所以在下面的例子中,config.json配置文件被读取。

viper.SetConfigFile("./config/config.yaml") //被覆盖了,不会被读取
viper.SetConfigFile("./config/config.json") //配置文件被读取,gin框架,端口:8080

err := viper.ReadInConfig() // 查找并读取配置文件
if err != nil {             // 处理读取配置文件的错误
    panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
mysql := viper.Get("mysql")
gin := viper.Get("gin")
fmt.Println(mysql)
fmt.Println(gin)

运行结果如下:

viper - 图2

第二种方式:多路径查找

viper.SetConfigName("config")
viper.AddConfigPath("D:\\GolandProjects\\ViperDemo\\config")

err := viper.ReadInConfig() // 查找并读取配置文件
if err != nil {             // 处理读取配置文件的错误
    panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
mysql := viper.Get("mysql")
gin := viper.Get("gin")
fmt.Println(mysql)
fmt.Println(gin)

SetConfigName()用来指定配置文件的名称(无扩展名),设置成功后viper只会读取以config开头的配置文件。
AddConfigPath()用来添加配置文件的路径,可以添加多个。但是,如果在同一个路径下有多个相同的配置文件名(扩展名不同),则只会读取第一个配置文件。
看看我上面的config目录下的文件顺序,所以只会读取config.json的配置信息,而config.yaml的配置信息会被忽略。运行结果如下:

viper - 图3

注册和使用别名

viper.Set("name", "green")
//为name设置一个username的别名
viper.RegisterAlias("username", "name")

//通过username可以读取到name的值
fmt.Println(viper.Get("username")) //green

//修改name的配置值,username的值也发生改变
viper.Set("name", "blue")
fmt.Println(viper.Get("username")) //blue

//修改username的值,name的值也发生改变
viper.Set("username", "red")
fmt.Println(viper.Get("name")) //red

来源:
作者:N-1-萘乙基二胺盐酸盐
链接:https://blog.csdn.net/qq_54015483/article/details/131120412