讀取Go項(xiàng)目中的配置文件的方法
Go語(yǔ)言提供了很簡(jiǎn)便的讀取json和yaml文件的api,我們可以很輕松將一個(gè)json或者yaml文件轉(zhuǎn)換成Go的結(jié)構(gòu)體,但是如果直接在項(xiàng)目中讀取配置文件,這種方式并不夠好。缺點(diǎn)如下:
實(shí)際開(kāi)發(fā)中配置項(xiàng)在不同環(huán)境下,配置的值是不同的
上面的問(wèn)題可以通過(guò)不同的配置文件去決定在那個(gè)環(huán)境讀取那個(gè)配置文件,但是還有一個(gè)問(wèn)題就是實(shí)際開(kāi)發(fā)中,配置項(xiàng)有些是相同的,有些是不同的,如果配置文件有一個(gè)主配置文件,里面存放的是不同環(huán)境相同的配置項(xiàng),還有一個(gè)跟隨環(huán)境的配置文件,里面存放的是不同環(huán)境的配置項(xiàng),然后讀取兩個(gè)配置文件后,做一個(gè)merge,這樣得到的結(jié)果就是總共的配置項(xiàng)信息。
有些配置項(xiàng)是必填的,有些配置項(xiàng)的值是一些特殊的值,比如,郵箱,手機(jī)號(hào),IP信息等
來(lái)看看gonfig是怎么解決這個(gè)問(wèn)題的
- 安裝gonfig
go get github.com/xiao-ren-wu/gonfig
- 項(xiàng)目中新建配置目錄,并編寫(xiě)對(duì)應(yīng)配置文件,在配置目錄同級(jí)目錄添加讀取配置文件的go文件
conf.yaml文件中存放的是通用的配置,conf-{{active}}.yaml中存放不同環(huán)境不同的配置信息。
conf |-conf.yaml |-conf-dev.yaml |-conf-prod.yaml |config.go
- 利用
go:embed將配置文件載入到內(nèi)存,調(diào)用gonfig.Unmarshal讀取配置文件
package config
import (
"model"
"github.com/xiao-ren-wu/gonfig"
"embed"
)
//go:embed *.yaml
var confDir embed.FS
// 我們配置文件的配置struct
type AppConf struct {
AppName string `yaml:"app-name" json:"app-name"`
DB DBConf `yaml:"db" json:"db"`
}
type DBConf struct {
Username string `yaml:"username" json:"username"`
Password string `yaml:"password" json:"password"`
}
var conf Conf
func Init() {
if err := gonfig.Unmarshal(confDir, &conf); err != nil {
panic(err)
}
}
func GetConf() *Conf {
return &conf
}這樣就完成了項(xiàng)目中配置文件的讀取,是不是很簡(jiǎn)單? 此時(shí)讀到的配置形式是conf-{{profile}}.yaml和conf.yaml的總和,如果conf-{{profile}}.yaml中定義的屬性和conf.yaml相同,那么會(huì)以conf-{{profile}}.yaml為準(zhǔn)
約定
gonfigAPI的簡(jiǎn)潔性的原因是因?yàn)楸澈笞隽撕芏嗉s束,只有符合約束的配置才能被成功讀取,具體的約束條件如下:
gonfig.Unmarshal會(huì)默認(rèn)讀取文件名稱有前綴conf的文件通過(guò)環(huán)境變量
profile作為環(huán)境名稱,如果沒(méi)有配置,默認(rèn)dev。程序會(huì)尋找
conf.yaml作為主配置文件,conf-{{profile}}.yaml作為環(huán)境特有配置文件,然后對(duì)文件內(nèi)容進(jìn)行合并如果
conf-{{profile}}.yaml中的屬性和conf.yaml中屬性都有定義,那么會(huì)以conf-{{profile}}.yaml為準(zhǔn)。
根據(jù)項(xiàng)目定制化配置文件
gonfig.Unmarshal的函數(shù)簽名func Unmarshal(confDir ReadFileDir, v interface{}, ops ...Option) error 提供很多配置項(xiàng),供用戶定制化需求,具體的配置信息如下:
更改配置文件名稱前綴
FilePrefix(prefix string)更改讀取配置文件類型
UnmarshalWith(uType UnmarshalType)更改讀取的環(huán)境變量名稱
ProfileUseEnv(envName, defaultProfile string)自定義設(shè)置profile
ProfileFunc(f func() string)
原理篇
gonfig的實(shí)現(xiàn)也很簡(jiǎn)單,核心的源碼如下:
func Unmarshal(confDir ReadFileDir, v interface{}, ops ...Option) error {
if v != nil && reflect.ValueOf(v).Kind() != reflect.Ptr {
return gonfig_error.ErrNonPointerArgument
}
var cs = &confStruct{
confPrefix: "conf",
envName: "profile",
defaultEnvValue: "dev",
unmarshalType: Yaml,
}
cs.activeProfileFunc = func() string {
return getActiveProfile(cs.envName, cs.defaultEnvValue)
}
for _, op := range ops {
op(cs)
}
cs.profileActive = cs.activeProfileFunc()
if err := loadConf(confDir, cs); err != nil {
return err
}
// copy val
v1 := reflect.New(reflect.TypeOf(v).Elem()).Interface()
if err := fileUnmarshal(cs.activeConfRaw, v1, cs.unmarshalType); err != nil {
return err
}
if len(cs.masterConfRaw) == 0 {
return gonfig_error.MasterProfileConfNotSetError
}
if err := fileUnmarshal(cs.masterConfRaw, v, cs.unmarshalType); err != nil {
return err
}
return mergo.Merge(v, v1, mergo.WithOverride)
}大概的原理就是復(fù)制了一份用戶傳給函數(shù)的結(jié)構(gòu)體v1,結(jié)構(gòu)體v1和v分別用于接收conf-{{profile}}.yaml中的屬性和conf.yaml的配置信息,然后通過(guò)調(diào)用三方開(kāi)源庫(kù)mergo對(duì)兩個(gè)結(jié)構(gòu)體的屬性做一個(gè)merge。
這就是關(guān)于gonfig的全部?jī)?nèi)容啦~~~
github地址是:https://github.com/xiao-ren-wu/gonfig
到此這篇關(guān)于讀取Go項(xiàng)目中的配置文件的方法的文章就介紹到這了,更多相關(guān)Go讀取配置文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go中使用gjson來(lái)操作JSON數(shù)據(jù)的實(shí)現(xiàn)
本文主要介紹了Go中使用gjson來(lái)操作JSON數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
Go?實(shí)現(xiàn)?WebSockets之創(chuàng)建?WebSockets
這篇文章主要介紹了Go?實(shí)現(xiàn)?WebSockets之創(chuàng)建?WebSockets,文章主要探索?WebSockets,并簡(jiǎn)要介紹了它們的工作原理,并仔細(xì)研究了全雙工通信,想了解更多相關(guān)內(nèi)容的小伙伴可以參考一下2022-04-04
Go項(xiàng)目編寫(xiě)Makefile規(guī)則文件概述
這篇文章主要為大家介紹了Go項(xiàng)目編寫(xiě)Makefile文件規(guī)則概述,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
Golang官方限流器庫(kù)實(shí)現(xiàn)限流示例詳解
這篇文章主要為大家介紹了Golang官方限流器庫(kù)使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Golang定時(shí)器的2種實(shí)現(xiàn)方法與區(qū)別
這篇文章主要給大家介紹了關(guān)于Golang定時(shí)器的2種實(shí)現(xiàn)方法與區(qū)別的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
go使用makefile腳本編譯應(yīng)用的方法小結(jié)
makefile可以看作是make工具的腳本文件, 而make主要用來(lái)處理一系列命令。常用的比如用來(lái)編譯和打包文件, 在C/C++的編譯打包中應(yīng)用最廣泛了,這篇文章主要介紹了go使用makefile腳本編譯應(yīng)用,需要的朋友可以參考下2022-08-08

