如何把Spring學精通了?

作爲 Java 後端工程師,幾乎都要用到 Spring,今天這篇文章是和大家說說如何學好 Spring。

在之前的一篇 Java 讀書路線的文章中,我介紹過 Spring 的讀書路線:

雖然 Spring 變化確實很快,但是,它有幾個地方,是這麼多年幾乎沒發生過什麼變化的。

沒有什麼變化的第一部分,就是 Spring 的設計思路。Spring 的設計思路,永遠都是作爲 Bean 的容器,去管理好 Bean ,這是它永恆不變的地方。

沒有什麼變化的第二部分,就是 Spring 的內核。Spring 的 ApplicationContext 等核心 API 是沒有什麼大的變化的。

所以,咱們就應該先從 Spring 這些不變的核心先入手。掌握住 Spring 的思想,Spring 的內核,哪怕 Spring 本身再變化,對咱們來說,也只是一種外在的 API 變化而已。

要達到這個目的,我會推薦大家看一本很老的書《Spring揭祕》(豆瓣 9.1分)。

雖然這本書主要是以 Spring3 的講解爲基礎,但是,這本書對於 Spring 的編程思想講的極爲透徹,是有關 Spring 的書中,難得一見的好書。入門 Spring,這是我推薦的第一本書。

理解了 Spring 的編程思想不夠,我們需要利用這些思想,去實踐演練,加強我們對 Spring 的理解。

這時候,就得有本書,能真正的帶我們實戰下Spring的各個組件——《精通Spring 4.x》(豆瓣 8.5 分)。

現在 Spring 5 在逐漸進入主流,但是 Spring 5 也只是在 Spring 4 的基礎上增加了一些新特性。

理解了 Spring 的理念,用很多代碼練習練習實踐之後,我們就只需要知道 Spring 5 的一些特性就能跟上 Spring 發展的步伐了。可以看下《Spring 5 開發大全》,這本書對 Spring 5 的新特性介紹很全。

關於 SpringBoot,由於它的易用性,它已經邁入主流。不過 SpringBoot 也只是以 Spring 爲內核的一套應用框架而已。找本書,學習它是如何通過添加一些模塊和功能,去降低大家使用 Spring 的門檻的,也就夠了。可以讀下《Spring Boot 2實戰之旅》。

接下來說說學Spring的具體步驟:

一、找到最核心的內容

學好 Spring 的第一步就是:從以上書籍或者其他書籍、資料文檔中,找到 Spring 龐大的知識體系中最核心最重要最值得學習的知識點,抽取出來形成學習清單。

例如,我提取的核心知識點是:

1. Spring 到底是如何管理對象的

我們使用 Spring 的時候,大部分其實都是在使用 Spring 的核心容器功能。

Spring 的容器功能就是通過 BeanFactory 和對應的子類各種 xxxContext 去存儲管理對象。

這個知識點是 Spring 發展至今一直沒有變化的核心知識。

2. Spring 注入對象的方式和對應原理

當 Spring 成爲對象容器後,它本身最重要的目的就是要去對系統中各種類進行對象注入。而工作中最常見的問題,就是 Spring 注入對象的各類問題。

也因此,廣泛瞭解 Spring 注入對象的各類方式,從而能更加靈活地運用 Spring,深入理解注入對象的對應原理,從而能順利無誤地使用 Spring,就是我們深入學習 Spring 的重要目標。

3. Spring 是如何管理對象之間的依賴關係的

除了使用完整對象的注入以外,工作中,我們還需要考慮對被注入對象屬性的動態修改,可能還想要動態地註冊新的 Bean 對象等等。

而要做到這些,我們就必須去了解 Spring 是如何管理對象之間的依賴關係的。

4. AOP 的實現原理以及對其的內部使用

AOP 在 Spring 項目中被廣泛用於權限、錯誤處理以及日誌追蹤等關鍵場景。

尤爲重要的是,Spring 項目中的所有相關數據庫事務,也都是通過 AOP 來管理和傳播的。

所以對 AOP 的學習也頗爲重要。

5. Spring 的擴展點有哪些以及如何做

很多時候,我們需要把公司的一些內部框架和系統嫁接到 Spring 中。爲了減少開發成本,就要自定義一套完整的 Spring 擴展,比如:自定義註解、自定義配置類等。

想做到這些,就必須知道 Spring 有哪些擴展點,可以做什麼擴展以及怎麼做擴展。

6. Spring MVC 的體系和重要類的作用

哪怕現在大家都使用 SpringBoot 了,但是,只要我們在用 SpringBoot 的 Web 功能,其實就是在和 SpringBoot 背後內置的 Spring MVC 打交道。

Spring MVC 本身有一套複雜的體系,從請求到響應,有一套完整複雜的流程。只有瞭解這些流程和 Spring MVC 的體系,我們才能順暢使用 Spring MVC,去解決 Web 項目中各種看起來很奇怪的問題以及作出新的擴展功能,比如,項目中的國際化出現的各種亂碼問題,統一錯誤處理問題等。

7. Spring Boot 是如何自動配置好類的

Spring Boot 本身就是以 Spring 作爲對象容器,以 Spring MVC 實現 Web 功能的一套縫合框架。學習了 Spring 和 Spring MVC 之後,我們就理解了 Spring Boot 絕大部分功能。

但是,Spring Boot 是如何把 Spring 中的各個組件縫合在一起的?其中重要的思想就是自動配置。

所以,學習了 Spring Boot 的自動配置,我們就能從頭到尾完整的瞭解 Spring Boot 的整體體系結構和相關對象管理流程。

提取出學習內容後,強烈建議大家學習中記下我們的筆記和思考,並定期複習。

說明一下:除了上述知識點,有一些知識點我沒說,例如:Spring MVC 中我並沒有提及攔截器,也沒有提及Spring Boot 中常用的各種註解。

之所以沒說,是因爲這些內容,是 Spring 必須內容,你繞不開他們。而我提及的這些,則是 Spring 學習中,大家經常不知所措,也不知道要學的那些重要內容。

二、做一些實際練習

學習上面知識點的過程中,應該結合實際的一些場景,再做一些練習。這裏我對應每個知識點給出一些練習建議,大家可以照着做一下。

  • 寫一個使用 AnnotationConfigApplicationContext 去獲取對象的測試用例:寫這個測試用例的目的是,讓我們能更加清楚地理解 Spring 是如何用容器管理對象的。

  • 寫一個能使用 FactoryBean 去產生一個對象的測試用例:目的是想讓大家明白,Spring 創建對象並不止是一種方式,大家可以多瞭解下其他的創建對象的方式,同時也多多思考。

  • 寫一個能在 Spring 中動態新增對象的測試用例。

  • 寫一個能在 Spring 中動態刪除對象的測試用例。

  • 寫一個能在 Spring 中動態修改Bean屬性的測試用例。

以上的測試用例,我建議大家使用 Spring 中的相關 BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor 等內部對象來實現,而不是簡單的從容器中獲取 Bean,然後採用反射去修改對應的值或者對象。

我們寫這幾個測試用例的目的是爲了讓大家對 Spring 是如何管理對象以及對象依賴關係的,有更進一步的體會。

  • 寫一個能觀察 Bean 的生命週期的測試用例:目的是能讓大家進一步瞭解 Spring 對象的管理。這個測試用例儘量寫全,生命週期觀察的越細緻越好。比如,我們不僅要實現 init 和 destroy 方法,還要採用 BeanNameAware、InitializingBean 等方式,去儘量把完整的 Bean 生命週期展示出來。

  • 寫一個或者幾個能用 AOP 功能的測試用例:加深對 Spring AOP 的理解的,最好是把 AOP 中的前置通知、後置通知、返回通知、異常通知、環繞通知都實現一遍,並通過調試,把整體的 AOP 流程搞得非常清楚。

  • 寫一套自定義註解並附上對應的測試用例:現在大家都使用 SpringBoot 了,普遍採用擴展 Spring 的方式就是自定義註解。所以,要理解 Spring 的自定義擴展點,就是要理解 Spring Boot 是如何做到自定義註解的。加載自定義註解,處理自定義註解,最好是通過寫出自定義註解的測試用例,然後一步步調試觀察出整個流程來。

  • 寫一個能手動映射 DispatcherServlet 路徑的測試用例:在 Spring MVC 中,DispatcherServlet 是所有 web 請求的第一關卡,是非常核心的類。寫關於 DispatcherServlet 的測試用例,我建議要想辦法通過編碼而不是配置去把 DispatcherServlet 相關的路徑映射等功能做出來。這對我們理解 Spring MVC 的請求路由,請求映射以及相關核心類的加載和使用都非常重要。

  • 寫一個自定義的 HttpMessageConverter 加對應的測試用例:自定義 HttpMessageConverter 是我們在使用 Spring 做 web 開發經常要做的一件事情。通過寫自定義的 HttpMessageConverter,以及對應的測試用例,對我們理解請求是如何被轉化成 Java 對象,Java 對象又是如何轉化成我們定義的響應內容格式的這個關鍵流程是非常重要的。

  • 自定義一個 WebDataBinder 並讓它生效:使用了 HttpMessageConverter 去轉化請求和響應,其中核心的一點是:在請求時如何把參數去綁定到對應的 Java 對象上。而在綁定參數過程中,數據校驗也經常和 WebDataBinder 混合在一起。所以理解 WebDataBinder,能更好理解 web 請求到 Spring 中 Java 對象的轉化機制。

  • 畫一張從請求到響應的 Spring MVC 所用到的類的流程圖:瞭解了 Spring MVC 中的幾個核心重要類,我們就可以把這些重要類關聯起來,並結合一些 Spring MVC 中別的相關類,共同構造出一幅完整的請求-響應流程圖,從而加深我們對 Spring MVC 整個體系的理解。

  • 自己實現一個 Spring Boot Starter:對於 Spring Boot,我們本身最重要的是去理解 Spring Boot 是如何通過自動配置,把各種 Spring 組件結合在一起的。而這種自動配置,其實就是通過各個組件寫自己的 Spring Boot Starter 來完成的。自己實現一個 Spring Boot Starter, 我們就能理解到 Spring Boot 的自動配置、自動加載方法。

三、通過項目融會貫通

做了練習後,我們就要通過一些小項目,去把學到的 Spring 知識融匯貫通,串聯到一起。我推薦做兩個簡單的項目:

第一個項目是做一個簡單的模擬銀行項目,需求如下:

  1. 可以檢查餘額
  2. 可以存款
  3. 可以退款
  4. 可以看到交易流水
  5. 可以計算利率
  6. 能優雅的退出應用

第二個項目是做一個簡單的員工管理系統,需求如下:

  1. 可以統計出今年的新員工有多少
  2. 輸入員工姓名的部分字,提示可能的全名
  3. 每個員工有五位的員工編號
  4. 員工有自己的部門和上級
  5. 可以顯示員工在職,離職狀態
  6. 有員工信息頁面,可以顯示員工編號,姓名,部門以及狀態

以上就是我自己總結出來的學習 Spring 的方法。

另外我還想提醒大家一句,學習 Spring,是爲了我們的工作服務的。所以,除了學習 Spring 本身,這裏,我還建議大家要經常關注一些 Spring 的實踐問題。把一些印象比較深的錯誤和對應的解決辦法彙總起來,看看有沒有什麼辦法能通過修改框架,增加約束,去減少這些錯誤的發生。

在從事技術的路上,我希望能一路分享給大家我自身的經驗。作爲多工作了幾年、多走了一些彎路的過來人,我希望能通過分享這些學習方法,爲大家撐起一把傘,陪伴着大家一路前行,畢竟,撐傘者也是雨中人,我們大家都只是在雨中砥礪前行而已。


你好,我是四猿外。

一家上市公司的技術總監,管理的技術團隊一百餘人。

我從一名非計算機專業的畢業生,轉行到程序員,一路打拼,一路成長。

我會把自己的成長故事寫成文章,把枯燥的技術文章寫成故事。

歡迎關注我的公衆號,關注後可以領取高併發、算法學習資料。

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