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 服務器的啓動函數,這裏只截取了其中的一部分,可以看到啓動函數的代碼太長了,而且需要精心組織才能保證代碼的可讀性。

clipboard.png

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

clipboard.png

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

clipboard.png

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

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

clipboard.png

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

clipboard.png

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

clipboard.png

▍自動綁定配置項,簡化配置文件使用

在使用了 Go-Spring 的代碼中只需要爲變量設置好要綁定的配置項的名稱,並在配置文件中添加該配置項,Go-Spring 就會自動幫你完成變量和配置項的綁定工作。

clipboard.png

Go-Spring 還支持按照運行環境綁定不同的配置文件,比如當檢測到線下環境時 Go-Spring 使用 application-test.properties 配置文件,而當檢測到線上環境時會使用 application-online.properties 配置文件。

clipboard.png

▍有效地幫助做好項目的依賴管理

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

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

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

3.
組件

Go-Spring 包含了四個核心項目,其中

clipboard.png

go-spring 實現了 IoC 容器和依賴注入等核心功能;

go-spring-boot 提供了自動配置及應用程序的啓動框架;

go-spring-cloud 立足開源世界打造人人可用的微服務框架;

go-spring-didi 聚焦滴滴內部技術實現具有滴滴特點的微服務框架。

4.
示例

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

  1. 新建 main.go 文件,創建啓動程序,並且指定配置文件所在目錄。

clipboard.png

  1. 在程序中引入 echo http 服務。

clipboard.png

  1. 新建 example.go 文件,實現一個示例服務,並且在 InitController() 函數中註冊 http 接口的路由。

clipboard.png

  1. 將一個示例服務的對象註冊到 Go-Spring 的 IoC 容器裏,這樣 Go-Spring 就能自動地加載用戶註冊的 http 接口的路由。

clipboard.png

  1. 在 main.go 文件中引入示例服務所在的包,這樣 Go-Spring 框架在啓動的時候就能加載示例服務所在的模塊。

clipboard.png

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

{"code":900001,"msg":"biz error"}

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

首先,我們可以編寫一個 TestMain 函數用於啓動真實的 http 服務器。

clipboard.png

實際上圖展示的代碼還可以更精簡,精簡爲一行。

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

clipboard.png

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

5.
總結

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

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

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

圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章