随笔 - 632  文章 - 17  评论 - 54  阅读 - 93万

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   飘杨......  阅读(194)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
历史上的今天:
2020-01-30 Android使用注解代替枚举从而节省系统使用的内存开销
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示