今天給大家分享幾個 Java 的開源類庫,親測非常好用!
有了它們之後,你就可以和很多重複勞動說再見了。

MapStruct是幹什麼的?
MapStruct是個代碼産生器,它能直接根據注解生成 Java 對象對應的轉換器。
比如,直接把一個 A 類型的 Java 對象,給轉成 B 類型的 Java 對象,隻需要在他們之間配置上字段之間的映射關系即可。
為什麼在項目裡用它?
現在随便一個項目都是多層的,尤其是 Web 項目,經常需要在多層之間做對象模型轉換,比如 DTO 轉換成 BO。
DTO(Data Transfer Object):資料傳輸對象,Service 向外傳輸的對象。 BO(Business Object):業務對象,由 Service 層輸出的封裝業務邏輯的對象。
但是這種轉換工作就像是小時候,老師罰我們抄寫名人名言 100 遍一樣,十分枯燥,還容易出錯。
像這樣:
要是 Car 有幾十個字段,像 Car 一樣的又有幾十個類,你可以想一下,這種繁瑣程度。
在 MapStruct 之前,我們都是通過 Apache 或者 Spring 的 BeanUtils 工具,去自動做這種事情。
但是這類工具有兩個問題:
1.性能比較差
性能差主要是 Apache 的 BeanUtils 這套東西,它每次都要針對字段,做是否可讀寫的檢查,還要根據字段生成對應的 PropertyDescriptor。
這些嚴重影響了它的性能,是以,在阿裡 Java 手冊裡,也不推薦用它。
Spring 的 BeanUtils,雖然精簡了很多 Apache 的 BeanUtils 的讀寫檢查以及對應的屬性資訊記錄,但是它依然是通過反射調用,而且是大量反射調用。這種性能也不能令人滿意。
2.運作期做轉換,出錯就代表損失
BeanUtils 這類工具,有個統一的名稱,叫做 Java 對象映射架構。
它們大部分的實作都是在運作期去執行代碼,然後在 Java 對象之間去拷貝對應的值。
運作期間做這種事兒,有個最大的問題——整個項目啟動運作後,才能發現錯誤。比如,轉換的時候,類型不一緻導緻報錯。
對于此種情況,咱們大家都知道,這事兒就像開業酬賓沒搞好,變成了開業仇賓……
如果能寫完代碼,編譯的時候就發現問題,這種損失就可以避免了。
MapStruct 的引入就是為了解決以上這兩個問題。
MapStruct 首先是個代碼産生器,它是根據注解,去産生一個專門用來轉換的工具類,這個工具類,就像我們自己寫的 Java 類一樣,可以直接被使用,這樣就避免了反射。
同時,它産生的轉換類也特别簡單,就是預設會在兩個類型的 Java 對象之間,拷貝同名屬性的值。
如果有了配置,屬性不同名也可以拷貝。是以它的性能很好。
示例代碼如下:
MapStruct由于是個代碼産生器,就帶來了個巨大的好處,就是這家夥是在編譯階段就會生成對應的類,是以,如果有了類似類型轉換不過去的問題,直接就編譯報錯了,根本等不到運作才發現。這樣的話,就不會造成什麼損失,這真是件十分 Nice 的事情。
代碼庫位址
https://github.com/mapstruct/mapstruct
Retrofit 是幹什麼的?
Retrofit 就是一套 Http 用戶端,可以用來通路第三方的 Http 服務。
比如,咱們代碼裡想調用一個 Http 協定的 URL,就可以用它來通路這個 URL,擷取響應結果。
在公司裡,我們有些項目有如下的特點:
不是基于 Spring 的項目
需要經常通路大量的第三方 Http 服務
通路 Http 服務的模型通常是異步回調
以前的時候,我們通路 Http 服務,都是直接用的 HttpClient。
可是吧,HttpClient 用起來實在夠麻煩的。主要也存在兩個問題:
1.請求參數和 URL 拼接實在繁瑣
請求參數和 URL 拼接實在是太煩人了。你想想,每調用一個接口,就需要自己去拼接參數,有的 URL,甚至十幾二十個參數需要拼接。
拼接這事兒簡單、枯燥、重複,還沒有技術含量,但是工作量卻不小,時間真的算浪費了。
2.異步回調需要自己搞
異步回調這種模型不好處理,主要就是需要自己去搞線程池,還要對線程池管理,還要考慮出錯的重試之類的容錯問題,實在麻煩。
是以,我們就需要一套能用法簡單,不用我們一直搞拼接參數,自己搞線程管理就能完成對第三方 Http 服務通路的庫。
其實我們也想過用 Feign 這套架構的。但是,這套東西和 Spring 綁定的太緊了。如果離開 Spring,它的一些功能就沒法簡單的通過注解直接使用,必須自己寫代碼調用。
而且,Feign 要實作異步回調方式使用,尤其在協程方面,還是需要自己開發。
這時候,Retrofit 就跳進了我們的選型裡。
Retrofit 的模型裡,異步回調模型它支援的很好,我們隻需要實作一個 Callable 就夠了。
并且最清爽的是,它和 Spring 沒什麼關系。
你看,隻需要寫上這些代碼,我們就不需要操心惱人的 Url 拼接和異步回調的管理問題了。全交給了 Retrofit,着實推薦。
https://github.com/square/retrofit
Faker 是幹什麼的?
Faker 是專門用來産生各種假資料的輔助工具庫。
比如,你想産生個和真實資料一樣的有姓名、有位址的使用者。
我們經常需要造資料去測試,但是,如果沒有工具輔助,我們自己造資料,存在一些問題。
1.資料是需要格式的
很多關于項目,都需要一些格式上盡量能模仿真實世界的資料。
比如,國内使用者的姓名,大部分都是兩字、三字的姓名,叫王大,就不能叫 王da 這種。
又比如,國内的位址是 xx市xx區xx街道xx号 這種的,就不能胡寫一個幾個沒意義的漢字來當位址。
用貼近真實格式的資料,一來可以測出我們對使用者的資料解析是否存在問題,二來可以測出資料庫内的字段長度是否沒問題。
是以,格式對産生出可靠地測試結果,是很重要的。
2.資料的量大
有的測試資料量都是上十萬、百萬的,這些量級的資料并不是隻會産生一次。
甚至幾乎每個項目,每個項目的每次測試,可能都會需要新的資料,需要能源源不斷地産生出來。
更甚至的是,有時候還想要根據我們的要求,在恰當的時候,産生某種關系的資料,或者以某些特定頻率産生。比如,兩秒後産生一次資料;比如,産生一批姓王的資料。
以上這三種要求綜合起來,要是我們自己造資料,那真是要了命了。
與其自己開發,不如用現成的——Faker 庫被我們找到了。
Faker庫可以創造三百多種資料,而且還很容易對它進行擴充改造,去産生更多的貼合我們需求的資料。
幾行代碼,我們需要的一個使用者就有了。
用上 Faker 後,小夥伴們紛紛表示“有更多的時間摸魚了”。
https://github.com/DiUS/java-faker
Wiremock 是幹什麼的?
Wiremock 是一個可以模拟服務的測試架構。
比如,你想測試通路阿裡的支付相關接口的代碼邏輯,就可以用它來做測試。
比如,我們需要調用銀行接口去做資金業務,調用微信接口去做微信登入……這些調用第三方服務的測試存在一個問題:
即太過依賴對方的平台。假如對方平台限制了一些 IP,或者限制了通路頻率,又或者就是服務出現了維護,都會影響我們自身的功能測試。
為了解決上述問題,在之前,我們需要自己寫代碼模仿第三方的接口,等我們自己全部測試沒問題了,再去和第三方聯調。對于這種模拟出來的接口,我們稱作擋闆。
可是,這種方式是個苦活,沒人願意幹。因為每接入一個第三方,可能都需要做擋闆。辛苦做個擋闆,就是單純為了測試。如果第三方的接口做了改造,你這邊還得跟着改。
大家可以想想,換成你自己,你願意做這麼件事兒嗎?
這時候,Wiremock 的價值就展現出來了。有了 Wiremock,擋闆這種東西就再也不存在了,直接在單元測試裡模拟測試即可,像這樣:
https://github.com/wiremock/wiremock
雖然 Java 有很多遭人诟病的地方,但是 Java 最重要的優點之一,就是它的生态,有其琳琅滿目的各種工具類庫。
希望大家都“懶”一點,不要埋頭去做無效的苦幹,不要自己造輪子,你要相信:
你遇到的問題,基本已經有很多人遇到過了,而且已經被牛人給解決了,把輪子都給你造好了。
你好,我是四猿外。
一家上市公司的技術總監,管理的技術團隊一百餘人。
我從一名非計算機專業的畢業生,轉行到程式員,一路打拼,一路成長。
我會把自己的成長故事寫成文章,把枯燥的技術文章寫成故事。
歡迎關注我的公衆号,關注後可以領取高并發、算法刷題筆記、計算機高分書單等學習資料。