Spring Boot 最流行的 16 條實踐解讀

點擊上方 "程序員小樂"關注, 星標或置頂一起成長

每天凌晨00點00分, 第一時間與你相約


每日英文

Never abandon an old friend. You will never find one who can take his place. Friendship is like wine, it gets better as it grows older.

不要輕易放棄舊朋友。因你不能找別人代替他。友情就像酒,越久越好。


每日掏心話

有一個夜晚我燒燬了所有的記憶,從此我的夢就透明瞭;有一個早晨我扔掉了所有的昨天,從此我的腳步就輕盈了 。


來自:e4developer.com/2018/08/06/

Spring Boot 最流行的 16 條實踐解讀

程序員小樂(ID:study_tech)第 800 次推文 圖片來自百度


往日回顧:Linux性能調優,從優化思路說起


正文


Spring Boot是最流行的用於開發微服務的Java框架。在本文中,我將與你分享自2016年以來我在專業開發中使用Spring Boot所採用的最佳實踐。這些內容是基於我的個人經驗和一些熟知的Spring Boot專家的文章。

在本文中,我將重點介紹Spring Boot特有的實踐(大多數時候,也適用於Spring項目)。以下依次列出了最佳實踐,排名不分先後。

1、使用自定義BOM來維護第三方依賴

這條實踐是我根據實際項目中的經歷總結出的。Spring Boot項目本身使用和集成了大量的開源項目,它幫助我們維護了這些第三方依賴。但是也有一部分在實際項目使用中並沒有包括進來,這就需要我們在項目中自己維護版本。如果在一個大型的項目中,包括了很多未開發模塊,那麼維護起來就非常的繁瑣。怎麼辦呢?事實上,Spring IO Platform就是做的這個事情,它本身就是Spring Boot的子項目,同時維護了其他第三方開源庫。我們可以借鑑Spring IO Platform來編寫自己的基礎項目platform-bom,所有的業務模塊項目應該以BOM的方式引入。這樣在升級第三方依賴時,就只需要升級這一個依賴的版本而已。<dependencymanagement><dependencies><dependency><groupid>io.spring.platform/<groupid><artifactid>platform-bom/<artifactid><version>Cairo-SR3/<version><type>pom/<type><scope>import/<scope>/<dependency>/<dependencies>/<dependencymanagement>


2、使用自動配置

Spring Boot的一個主要特性是使用自動配置。這是Spring Boot的一部分,它可以簡化你的代碼並使之工作。當在類路徑上檢測到特定的jar文件時,自動配置就會被激活。使用它的最簡單方法是依賴Spring Boot Starters。因此,如果你想與Redis進行集成,你可以首先包括:<dependency><groupid>org.springframework.boot/<groupid><artifactid>spring-boot-starter-data-redis/<artifactid>/<dependency>
如果你想與MongoDB進行集成,需要這樣:<dependency><groupid>org.springframework.boot/<groupid><artifactid>spring-boot-starter-data-mongodb/<artifactid>/<dependency>

藉助於這些starters,這些繁瑣的配置就可以很好地集成起來並協同工作,而且它們都是經過測試和驗證的。這非常有助於避免可怕的Jar地獄。

https://dzone.com/articles/what-is-jar-hell

通過使用以下註解屬性,可以從自動配置中排除某些配置類:

@EnableAutoConfiguration(exclude = {ClassNotToAutoconfigure.class})

但只有在絕對必要時才應該這樣做。

有關自動配置的官方文檔可在此處找到:

https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html。

3、使用Spring Initializr來開始一個新的Spring Boot項目

這一條最佳實踐來自Josh Long (Spring Advocate,@starbuxman)。

Spring Initializr 提供了一個超級簡單的方法來創建一個新的Spring Boot項目,並根據你的需要來加載可能使用到的依賴。

https://start.spring.io/

使用Initializr創建應用程序可確保你獲得經過測試和驗證的依賴項,這些依賴項適用於Spring自動配置。你甚至可能會發現一些新的集成,但你可能並沒有意識到這些。

4、考慮為常見的組織問題創建自己的自動配置

這一條也來自Josh Long(Spring Advocate,@starbuxman)——這個實踐是針對高級用戶的。

如果你在一個嚴重依賴Spring Boot的公司或團隊中工作,並且有共同的問題需要解決,那麼你可以創建自己的自動配置。

這項任務涉及較多工作,因此你需要考慮何時獲益是值得投入的。與多個略有不同的定製配置相比,維護單個自動配置更容易。

如果將這個提供Spring Boot配置以開源庫的形式發佈出去,那麼將極大地簡化數千個用戶的配置工作。

5、正確設計代碼目錄結構

儘管允許你有很大的自由,但是有一些基本規則值得遵守來設計你的源代碼結構。

避免使用默認包。確保所有內容(包括你的入口點)都位於一個名稱很好的包中,這樣就可以避免與裝配和組件掃描相關的意外情況;

將Application.java(應用的入口類)保留在頂級源代碼目錄中;

我建議將控制器和服務放在以功能為導向的模塊中,但這是可選的。一些非常好的開發人員建議將所有控制器放在一起。不論怎樣,堅持一種風格!

6、保持@Controller的簡潔和專注

Controller應該非常簡單。你可以在此處閱讀有關GRASP中有關控制器模式部分的說明。你希望控制器作為協調和委派的角色,而不是執行實際的業務邏輯。以下是主要做法:

https://en.wikipedia.org/wiki/GRASP(object-orienteddesign)#Controller


  • 控制器應該是無狀態的!默認情況下,控制器是單例,並且任何狀態都可能導致大量問題;

  • 控制器不應該執行業務邏輯,而是依賴委託;

  • 控制器應該處理應用程序的HTTP層,這不應該傳遞給服務;

  • 控制器應該圍繞用例/業務能力來設計。


要深入這個內容,需要進一步地瞭解設計REST API的最佳實踐。無論你是否想要使用Spring Boot,都是值得學習的。

7、圍繞業務功能構建@Service

Service是Spring Boot的另一個核心概念。我發現最好圍繞業務功能/領域/用例(無論你怎麼稱呼都行)來構建服務。

在應用中設計名稱類似 AccountService, UserService, PaymentService這樣的服務,比起像 DatabaseService、 ValidationService、 CalculationService這樣的會更合適一些。

你可以決定使用Controler和Service之間的一對一映射,那將是理想的情況。但這並不意味著,Service之間不能互相調用!

8、使數據庫獨立於核心業務邏輯之外

我之前還不確定如何在Spring Boot中最好地處理數據庫交互。在閱讀了羅伯特·C·馬丁的“Clear Architecture”之後,對我來說就清晰多了。

你希望你的數據庫邏輯於服務分離出來。理想情況下,你不希望服務知道它正在與哪個數據庫通信,這需要一些抽象來封裝對象的持久性。

羅伯特C.馬丁強烈地說明,你的數據庫是一個“細節”,這意味著不將你的應用程序與特定數據庫耦合。過去很少有人會切換數據庫,我注意到,使用Spring Boot和現代微服務開發會讓事情變得更快。

9、保持業務邏輯不受Spring Boot代碼的影響

考慮到“Clear Architecture”的教訓,你還應該保護你的業務邏輯。將各種Spring Boot代碼混合在一起是非常誘人的……不要這樣做。如果你能抵制誘惑,你將保持你的業務邏輯可重用。

部分服務通常成為庫。如果不從代碼中刪除大量Spring註解,則更容易創建。

10、推薦使用構造函數注入

這一條實踐來自Phil Webb(Spring Boot的項目負責人, @phillip_webb)。

保持業務邏輯免受Spring Boot代碼侵入的一種方法是使用構造函數注入。不僅是因為 @Autowired註解在構造函數上是可選的,而且還可以在沒有Spring的情況下輕鬆實例化bean。

11、熟悉併發模型

我寫過的最受歡迎的文章之一是“介紹Spring Boot中的併發”。我認為這樣做的原因是這個領域經常被誤解和忽視。如果使用不當,就會出現問題。

https://www.e4developer.com/2018/03/30/introduction-to-concurrency-in-spring-boot/

在Spring Boot中,Controller和Service是默認是單例。如果你不小心,這會引入可能的併發問題。你通常也在處理有限的線程池。請熟悉這些概念。

如果你正在使用新的WebFlux風格的Spring Boot應用程序,我已經解釋了它在“Spring’s WebFlux/Reactor Parallelism and Backpressure”中是如何工作的。

12、加強配置管理的外部化

這一點超出了Spring Boot,雖然這是人們開始創建多個類似服務時常見的問題……

你可以手動處理Spring應用程序的配置。如果你正在處理多個Spring Boot應用程序,則需要使配置管理能力更加強大。

我推薦兩種主要方法:


  • 使用配置服務器,例如Spring Cloud Config;

  • 將所有配置存儲在環境變量中(可以基於git倉庫進行配置)。


這些選項中的任何一個(第二個選項多一些)都要求你在DevOps更少工作量,但這在微服務領域是很常見的。

13、提供全局異常處理

你真的需要一種處理異常的一致方法。Spring Boot提供了兩種主要方法:


  • 你應該使用HandlerExceptionResolver定義全局異常處理策略;

  • 你也可以在控制器上添加@ExceptionHandler註解,這在某些特定場景下使用可能會很有用。


這與Spring中的幾乎相同,並且Baeldung有一篇關於REST與Spring的錯誤處理的詳細文章,非常值得一讀。

https://www.baeldung.com/exception-handling-for-rest-with-spring

14、使用日誌框架

你可能已經意識到這一點,但你應該使用Logger進行日誌記錄,而不是使用System.out.println()手動執行。這很容易在Spring Boot中完成,幾乎沒有配置。只需獲取該類的記錄器實例:

Logger logger = LoggerFactory.getLogger(MyClass.class);

這很重要,因為它可以讓你根據需要設置不同的日誌記錄級別。

15、測試你的代碼

這不是Spring Boot特有的,但它需要提醒——測試你的代碼!如果你沒有編寫測試,那麼你將從一開始就編寫遺留代碼。

如果有其他人使用你的代碼庫,那邊改變任何東西將會變得危險。當你有多個服務相互依賴時,這甚至可能更具風險。

由於存在Spring Boot最佳實踐,因此你應該考慮將Spring Cloud Contract用於你的消費者驅動契約,它將使你與其他服務的集成更容易使用。

16、使用測試切片讓測試更容易,並且更專注

這一條實踐來自Madhura Bhave(Spring 開發者, @madhurabhave23)。

使用Spring Boot測試代碼可能很棘手——你需要初始化數據層,連接大量服務,模擬事物……實際上並不是那麼難!答案是使用測試切片。

使用測試切片,你可以根據需要僅連接部分應用程序。這可以為你節省大量時間,並確保你的測試不會與未使用的內容相關聯。來自spring.io的一篇名為Custom test slice with Spring test 1.4的博客文章解釋了這種技術。

https://spring.io/blog/2016/08/30/custom-test-slice-with-spring-boot-1-4

總結

感謝Spring Boot,編寫基於Spring的微服務正變得前所未有的簡單。我希望通過這些最佳實踐,你的實施過程不僅會變得很快,而且從長遠來看也會更加強大和成功。祝你好運!

Spring Boot 最流行的 16 條實踐解讀

歡迎在留言區留下你的觀點,一起討論提高。如果今天的文章讓你有新的啟發,學習能力的提升上有新的認識,歡迎轉發分享給更多人。


猜你還想看


阿里、騰訊、百度、華為、京東最新面試題彙集

必須要掌握的 InterruptedException 異常處理

Git 居然還有這麼高級用法,你一定需要

Java編程性能優化一些事兒

關注訂閱號「程序員小樂」,收看更多精彩內容
嘿,你在看嗎?


分享到:


相關文章: