網站首頁 編程語言 正文
Go語言提供了很簡便的讀取json和yaml文件的api,我們可以很輕松將一個json或者yaml文件轉換成Go的結構體,但是如果直接在項目中讀取配置文件,這種方式并不夠好。缺點如下:
實際開發中配置項在不同環境下,配置的值是不同的
上面的問題可以通過不同的配置文件去決定在那個環境讀取那個配置文件,但是還有一個問題就是實際開發中,配置項有些是相同的,有些是不同的,如果配置文件有一個主配置文件,里面存放的是不同環境相同的配置項,還有一個跟隨環境的配置文件,里面存放的是不同環境的配置項,然后讀取兩個配置文件后,做一個merge,這樣得到的結果就是總共的配置項信息。
有些配置項是必填的,有些配置項的值是一些特殊的值,比如,郵箱,手機號,IP信息等
來看看gonfig是怎么解決這個問題的
- 安裝gonfig
go get github.com/xiao-ren-wu/gonfig
- 項目中新建配置目錄,并編寫對應配置文件,在配置目錄同級目錄添加讀取配置文件的go文件
conf.yaml
文件中存放的是通用的配置,conf-{{active}}.yaml
中存放不同環境不同的配置信息。
conf |-conf.yaml |-conf-dev.yaml |-conf-prod.yaml |config.go
- 利用
go:embed
將配置文件載入到內存,調用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 }
這樣就完成了項目中配置文件的讀取,是不是很簡單? 此時讀到的配置形式是conf-{{profile}}.yaml
和conf.yaml
的總和,如果conf-{{profile}}.yaml
中定義的屬性和conf.yaml
相同,那么會以conf-{{profile}}.yaml
為準
約定
gonfig
API的簡潔性的原因是因為背后做了很多約束,只有符合約束的配置才能被成功讀取,具體的約束條件如下:
gonfig.Unmarshal
會默認讀取文件名稱有前綴conf
的文件通過環境變量
profile
作為環境名稱,如果沒有配置,默認dev。程序會尋找
conf.yaml
作為主配置文件,conf-{{profile}}.yaml
作為環境特有配置文件,然后對文件內容進行合并如果
conf-{{profile}}.yaml
中的屬性和conf.yaml
中屬性都有定義,那么會以conf-{{profile}}.yaml
為準。
根據項目定制化配置文件
gonfig.Unmarshal
的函數簽名func Unmarshal(confDir ReadFileDir, v interface{}, ops ...Option) error
提供很多配置項,供用戶定制化需求,具體的配置信息如下:
更改配置文件名稱前綴
FilePrefix(prefix string)
更改讀取配置文件類型
UnmarshalWith(uType UnmarshalType)
更改讀取的環境變量名稱
ProfileUseEnv(envName, defaultProfile string)
自定義設置profile
ProfileFunc(f func() string)
原理篇
gonfig
的實現也很簡單,核心的源碼如下:
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) }
大概的原理就是復制了一份用戶傳給函數的結構體v1,結構體v1和v分別用于接收conf-{{profile}}.yaml
中的屬性和conf.yaml
的配置信息,然后通過調用三方開源庫mergo
對兩個結構體的屬性做一個merge。
這就是關于gonfig
的全部內容啦~~~
github地址是:https://github.com/xiao-ren-wu/gonfig
原文鏈接:https://juejin.cn/post/7109846075950759950
相關推薦
- 2022-07-22 yaml文件的加載使用
- 2022-07-13 Sybase使用Spring的只讀事物報 Use ‘set readonly off‘ to exe
- 2022-04-06 關于Redis數據庫三種持久化方案介紹_Redis
- 2022-07-04 PyTorch計算損失函數對模型參數的Hessian矩陣示例_python
- 2023-06-04 Pandas通過index選擇并獲取行和列_python
- 2022-03-08 c++實現超簡單的貪吃蛇游戲實例介紹_C 語言
- 2022-07-25 C++超詳細講解內存空間分配與this指針_C 語言
- 2023-06-13 C語言中函數返回值不一致問題_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支