Golang之服務配置自動初始化

原文出處:dpjeep.com/golangzhi-p…git

背景

今天分享一個利用reflect在實際項目中比較省時、代碼簡潔且高效的方法-服務配置自動初始化的方法。 咱們在起一個Web項目時,經常都是直接使用開源的一些框架或組建,而後在咱們本身的項目中要使用以前按照該框架或組建提供的幫助文檔一個一個進行相應的初始化配置。也許咱們只引用其中一兩個,這樣寫都還能忍受,但是若是這個服務會引用更多的呢? github

自行腦補

效果

1

  1. 代碼簡潔化
  2. 接入第三方庫就如搭積木同樣,模塊化,隨取隨用
  3. 可維護性高

乾貨

下面,咱們就來利用reflect實現該功能。golang

思路

磨刀不誤砍柴工,咱們先整理好一個簡單思路,而後再嘗試實現它,這樣就簡單了。json

  • 從遠端配置服務或本地獲取到咱們須要初始化的配置
  • 解析配置中的數據
  • 判斷配置中元素是否有實現咱們指定方法,若是有就執行它,沒有就跳過 沒錯,用語言描述就這麼三句話,就這麼簡單。

獲取配置

服務要啓動,獲取配置要麼從遠端配置服務拉取,要麼從本地讀取,就以常見的json格式做爲咱們本次舉例的配置格式吧。框架

{
    "ginx": {
        "listen_port": 8080
    },
    "conn_timeout":2
}
複製代碼

既然是json化的配置,那咱們就須要一個struct結構體來對配置進行反解析,這個貌似沒什麼好說的。模塊化

type Cfg struct {
	ConnTimeout int        `json:"conn_timeout"`
	Ginx        *ginx.Ginx `json:"ginx"`
	// other config
}
複製代碼

其中ginx.Ginx是咱們自定義的一個結構體。spa

查找結構體中是否包含某方法

type ICanInit interface {
	Init()
}

func InitialRoot(rv reflect.Value) {
	tpe := rv.Type()
	for i := 0; i < tpe.NumField(); i++ {
		value := rv.Field(i)
		if conf, ok := value.Interface().(ICanInit); ok {
			conf.Init()
		}
	}
}
複製代碼

對,上面的這個就是判斷某結構體中是否已實現Init()方法,有的話就執行它。這個就是實現這個功能的核心,是否是很簡單?哈哈。 咱們在實現這個功能以前,只須要對配置結構體進行一下簡單的類型判斷就OK了。code

總結

reflect的用處遠不止於此,多總結,而後付諸行動。cdn

若有興趣,源碼在此blog

相關文章
相關標籤/搜索