1. 程式人生 > 程式設計 >Go-Spring : Another Go Style!

Go-Spring : Another Go Style!

Go-Spring 是模仿 Java 的 Spring 全家桶實現的一套 GoLang 的應用程式框架,仍然遵循“習慣優於配置”的原則,提供了依賴注入、自動配置、開箱即用、豐富的第三方類庫整合等功能,能夠讓程式設計師少寫很多的樣板程式碼。

1.前言

去年年底的時候,我所在的團隊由於業務調整,技術棧也隨之發生改變,由之前的 PHP +Java 變成了 Golang + Java。初次接觸 Golang,頗不適應,首先就是它那不同一般的語法,然後是沒有一個成熟好用的開發框架。語法問題時間長了程式碼寫的多了也就慢慢適應了,但是沒有順手的開發框架就太影響開發效率和程式碼質量了,作為一個資深的 Java + Spring 全家桶開發者,我希望能改變這一現狀。經過一段時間的使用和探索,我發現完全可以搞出一套像 Spring 全家桶(Spring Framework + Spring Boot +Spring Cloud)那樣的解決方案出來!

Spring 全家桶在 Java 世界的地位自然無需多言,它不僅為 Java 開發者證明瞭基於註解開發、基於 AOP 開發以及面向介面開發能夠給程式帶來極大的靈活性,更重要的是帶來了依賴注入、宣告式事務、統一的異常處理、模組自動化載入、更簡單的 Maven 管理、更簡單的單元測試等優秀的開發實踐。

但是 GoLang 和 Java 畢竟不同,我為什麼篤信自己肯定能搞出來呢?要回答這個問題,實際上是在回答另一個問題,即 Java 的哪些語言特性支撐了 Spring 全家桶能夠實現那些核心能力,而 GoLang 又有哪些相似的語言特性?

追根溯源,Java 的位元組碼、反射、註解、包掃描等機制支撐了 Spring 全家桶能夠實現 AOP 開發、依賴注入、宣告式事務、模組自動化載入等核心特性。GoLang 因為沒有位元組碼,所以不能實現 AOP 。但是 GoLang 有 Tags、Reflection、_ Imports、init() 機制,所以儘管實現起來不一定有 Java 優雅,但是也能實現依賴注入、模組自動化載入這些 Spring 全家桶的最核心特性。而且,儘管 GoLang 無法實現 AOP,但是也可以通過 Middleware 實現同樣的功能。

經過一番探索和實踐,終於 Go-Spring 誕生了!在我的眼中,Go-Spring 和 GoLang 本身一樣,一出生就帶著叛逆和創新精神,GoLang 以不同於主流程式語言語法的姿態出現,而 Go-Spring 則在質疑中以面向介面和依賴注入等多種絕對 Java 的特性出現在大家眼前。

2.特性

Go-Spring 是模仿 Java 的 Spring 全家桶實現的一套 GoLang 的應用程式框架,仍然遵循“習慣優於配置”的原則,提供了依賴注入、自動配置、開箱即用、豐富的第三方類庫整合等功能,能夠讓程式設計師少寫很多的樣板程式碼。總結起來,Go-Spring 至少有以下五大特點:

▍可擴充套件的啟動器框架,幫你優雅的組織程式碼

下面這張圖展示了一個 rtmp 伺服器的啟動函式,這裡只截取了其中的一部分,可以看到啟動函式的程式碼太長了,而且需要精心組織才能保證程式碼的可讀性。


而使用 Go-Spring 的啟動器框架則可以把這些啟動過程封裝到單獨的檔案中,使得功能更內聚,程式碼更清晰。下圖展示的就是一個封裝好的啟動檔案。


在使用了 Go-Spring 的啟動器框架之後,程式的啟動過程就變成了非常簡單的一行程式碼了!


▍面向介面+依賴注入,靈活替換實現方案

Go-Spring 為 Redis 服務提供了統一的 API 介面,但是底層實現卻有多種方案。使用者在使用 Redis 服務編寫業務程式碼時只需要關注 API 介面,而不需要關心底層採用的是哪種方案。


當然使用者最終會選擇一個 redis 服務的底層實現,而引入這個實現僅僅只需要一行程式碼即可!


如果你想換成其他的 redis 底層實現,也僅僅是一行程式碼的事。

▍自動繫結配置項,簡化配置檔案使用

在使用了 Go-Spring 的程式碼中只需要為變數設定好要繫結的配置項的名稱,並在配置檔案中新增該配置項,Go-Spring 就會自動幫你完成變數和配置項的繫結工作。


Go-Spring 還支援按照執行環境繫結不同的配置檔案,比如當檢測到線下環境時 Go-Spring 使用 application-test.properties 配置檔案,而當檢測到線上環境時會使用 application-online.properties 配置檔案。


▍有效地幫助做好專案的依賴管理

Go-Spring 為每一個模組都提供了一個抽象介面,使用者不需要關心介面內部是怎麼實現的,這樣能非常容易的解決依賴升級的問題。Go-Spring 保證已釋出的所有版本的專案依賴都是正確的,而且 Go-Spring 每釋出一個版本都會對依賴進行升級,這樣使用者只需要關注 Go-Spring 的版本變化,就能享受到其他依賴自動升級的好處!

▍讓複雜的單元測試變得更簡單

GoLang 的單元測試尤其對 http 的單元測試簡直爛的要命!使用 Go-Spring 啟動的專案能夠在單元測試的時候使用真實的專案執行環境,而不是使用一個 fake 的 http 環境。

3.元件

Go-Spring 包含了四個核心專案,其中:


  • go-spring 實現了 IoC 容器和依賴注入等核心功能;
  • go-spring-boot 提供了自動配置及應用程式的啟動框架;
  • go-spring-cloud 立足開源世界打造人人可用的微服務框架;
  • go-spring-didi 聚焦滴滴內部技術實現具有滴滴特點的微服務框架。

4.示例

下面我將通過一個最簡單的 http 服務為大家展示如何使用 Go-Spring。

1. 新建 main.go 檔案,建立啟動程式,並且指定配置檔案所在目錄。


2. 在程式中引入 echo http 服務。


3. 新建 example.go 檔案,實現一個示例服務,並且在 InitControllr() 函式中註冊 http 介面的路由。


4. 將一個示例服務的物件註冊到 Go-Spring 的 IoC 容器裡,這樣 Go-Spring 就能自動地載入使用者註冊的 http 介面的路由。


5. 在 main.go 檔案中引入示例服務所在的包,這樣 Go-Spring 框架在啟動的時候就能載入示例服務所在的模組。

通過上面的 5 個步驟我們就得到了一個簡單但完整的 http 服務,使用 go run main.go 命令啟動程式,並使用 curl http://localhost:8080/ 進行測試,可以看到請求的返回結果如下:

{"code":900001,"msg":"biz error"}複製程式碼

OK,是不是已經開始感覺到 Go-Spring 的威力了!下面我們再來看一下使用了 Go-Spring 框架的專案的單元測試會怎麼寫。

首先,我們可以編寫一個 TestMain 函式用於啟動真實的 http 伺服器。

實際上圖展示的程式碼還可以更精簡,精簡為一行。

然後,我們可以編寫一個測試函式傳送真實的 http 請求,也不需要 fake 或者 mock。

執行這個單元測試,你就會發現,你得到了一個完全不用 mock 和 fake ,並且功能完整、可以斷點除錯的測試環境。

5.總結

除了上面展示的能夠建立 http 服務和單元測試之外,Go-Spring 已經支援了 mysql 服務、redis 服務、kafka 服務、ddmq服務、服務註冊和服務發現服務以及多種 rpc 服務,並且更多的新元件和新特性正在源源不斷的通過滴滴內源加入進來,未來 Go-Spring 會變得越來越完善,越來越好用!

Another Go Style!我個人認為 Go-Spring 代表了一種新的程式設計模式,甚至是一種新的生產力方式,我希望大家在使用 Go-Spring 的過程中能夠解放思想,提高效率,得到更多的快樂和自由,也多留一些時間給朋友和家人!

本文首發自普惠出行產品技術 (ID:pzcxtech)