Viper基本操作

一、概述

  Viper主要是操作:

    1.读取命令行参数

    2.读取环境变量

    3.读取配置文件

    这比配置参数直接写在代码中方便的多,而且还支持配置热加载

  导入viper

go get -u github.com/spf13/viper

 

二、代码示例

  1.在代码中读取设置默认配置

// 读取默认配置
func main001() {
    //设置viper默认配置
    viper.SetDefault("username", "tony")
    viper.SetDefault("server", map[string]string{"ip": "127.0.0.1", "port": "8888"})

    //读取默认配置
    fmt.Println("username:", viper.Get("username"))
    fmt.Println("server:", viper.Get("server"))

    //从配置文件中读取配置

    fmt.Println("Hello World!")
}

  2.解析配置文件:config.yaml

func main002() {
    // flag.Parse() //解析命令行参数

    // viper.SetConfigFile("config.yaml")
    // if *cfg != "" {
    viper.SetConfigFile("config.yaml")
    //如果配置文件没有后缀,则主动指定文件后缀
    // viper.SetConfigType("yaml")
    // } else {
    // viper.AddConfigPath(".")                  //把当前目录加入到配置文件的搜索路径中
    // viper.AddConfigPath("$HOME/.config.yaml") //可以多次调用AddConfigPath来设置多个配置文件路径
    // viper.SetConfigName("config")             //指定配置文件扩展名(如果没有扩展名)
    // }

    //读取配置文件

    if err := viper.ReadInConfig(); err != nil {
        if _, ok := err.(viper.ConfigFileNotFoundError); ok {
            fmt.Println(errors.New("config file not found"))
        } else {
            fmt.Println(errors.New("config file was found but another error was product"))
        }
        return
    }
    fmt.Println("viper.ConfigFileUsed", viper.ConfigFileUsed()) //读取配置文件的路径
    //读取配置值
    fmt.Println("username", viper.Get("username"))
    fmt.Println("password", viper.Get("password"))
    fmt.Println("server", viper.Get("server"))
    server := viper.Get("server")
    serverMap, ok := server.(map[string]interface{}) //把Server转换成为一个map
    if !ok {
        fmt.Println("类型转换失败")
        return
    }
    fmt.Println("ip", serverMap["ip"])
    fmt.Println("port", serverMap["port"])
    fmt.Println("ip2", viper.Get("server.ip"))
    fmt.Println("port2", viper.Get("server.port"))

    // serverMap,ok:=viper.Get("server").(map[string]interface)
    // fmt.Println("ip", viper.Get("server")["ip"])
    // fmt.Println("port", viper.Get("server")["port"])

}

  3.监控并重新配置文件(热加载)

// 监控并重新读取配置文件(热加载),这块已经做了测试可以正常的读取变化后的内容
func main003() {
    viper.SetConfigFile("config.yaml") //加载配置文件
    viper.ReadInConfig()

    //注册回调函数:每次配置文件发生变更的时候回调
    viper.OnConfigChange(func(e fsnotify.Event) {
        fmt.Println("配置文件发生变化", e.Name)
    })
    //监控并重新读取配置文件,需要确保调用前添加了所有配置路径
    viper.WatchConfig()

    time.Sleep(time.Second * 10) //主要是观察输出用的

    //读取配置信息
    fmt.Println("server.ip", viper.Get("server.ip"))
    fmt.Println("username", viper.Get("username"))

}

  4.从io.Reader中读取配置

// 从io.Reader中读取配置
func main004() {
    viper.SetConfigType("yaml")
    var yamlExample = []byte(`
username: 杨洛峋
password: 123456
server:
  ip: 127.0.0.1
  port: 8289
`)
    viper.ReadConfig(bytes.NewBuffer(yamlExample))
    //读取配置信息
    fmt.Println("username", viper.Get("username"))
    fmt.Println("password", viper.Get("password"))
    fmt.Println("server.ip", viper.Get("server.ip"))
    fmt.Println("server.port", viper.Get("server.port"))
}

  5.读取子树

// 提取子树
func main005() {
    viper.SetConfigFile("config.yaml")
    viper.ReadInConfig()

    //提取子树
    subConf := viper.Sub("server")
    fmt.Println("ip", subConf.Get("ip"))
    fmt.Println("port", subConf.Get("port"))
}

  6.反序列化

//反序列化
type Config struct {
    UserName string
    Password string
    Server   struct {
        IP   string
        Port int
    }
}

func main006() {
    //加载并读取配置文件
    viper.SetConfigFile("config.yaml")
    viper.ReadInConfig()

    //将配置文件序列化到Config结构体中
    var cfg *Config
    if err := viper.Unmarshal(&cfg); err != nil { //反序列化所有配置项
        panic(err)
    }

    var password *string
    if err := viper.UnmarshalKey("password", &password); err != nil { //反序列化指定配置项(这里指定的是password)
        panic(err)
    }

    //获取反序列化所有配置项的结果
    fmt.Println("config", cfg)
    fmt.Println("username", cfg.UserName)
    fmt.Println("password", cfg.Password)
    fmt.Println("IP", cfg.Server.IP)
    fmt.Println("Port", cfg.Server.Port)

    //获取序列化指定配置项的结果
    fmt.Println("password", *password)

}

  7.Viper多实例测试

// viper多实例测试(切换开发环境、测试环境、生产环境)
func main() {
    viper.SetConfigFile("config.yaml")
    err := viper.ReadInConfig()
    if err != nil {
        fmt.Println("读取配置文件失败")
        return
    }

    mType := viper.Get("type")
    fmt.Println("mType", mType)
    if mType == 1 {
        fmt.Println("开发环境")
        dev := viper.New()
        dev.SetConfigFile("dev.yaml")
        dev.ReadInConfig()
        fmt.Println("dev->username", dev.Get("username"))
    } else if mType == 2 {
        fmt.Println("测试环境")
        uat := viper.New()
        uat.SetConfigFile("uat.yaml")
        uat.ReadInConfig()
        fmt.Println("uat->username", uat.Get("username"))
    } else if mType == 3 {
        pro := viper.New()
        pro.SetConfigFile("pro.yaml")
        pro.ReadInConfig()
        fmt.Println("pro->username", pro.Get("username"))
        fmt.Println("生产环境")
    }
}

 

posted on 2024-01-30 15:19  飘杨......  阅读(279)  评论(0)    收藏  举报