這應該是最通俗易懂的一篇Spring知識點總結了

由於Spring家族的東西很多,一次性寫完也不太現實。所以這一次先更新Spring「最核心」的知識點:

AOP和IOC

無論是入門還是面試,理解AOP和IOC都是非常重要的。在校招的時候,我沒被問過Mybatis/Hibernate/Struts2這樣的框架,而Spring就經常會被問到。

這應該是最通俗易懂的一篇Spring知識點總結了


為什麼要用Spring

當年的我,剛學Spring的時候,會想:『這IOC和AOP』是什麼鬼玩意啊?一大堆的名詞「控制反轉」「依賴注入」「面向切面編程」。這是在給我搞笑的吧。

這應該是最通俗易懂的一篇Spring知識點總結了

在最開始學的IOC折騰了一大堆的玩意,結果就是在管「創建對象」的事??逗我呢???我直接new一個對象出來不香嗎?

有這種想法這種明顯就是「代碼寫得少了,想得多了

這應該是最通俗易懂的一篇Spring知識點總結了

我們寫代碼,不僅僅是要能實現功能,實現完了以後我們還得對寫過的代碼「

維護」。如果我們的代碼寫得很爛,那「維護」的成本就很高。

維護實際上是做什麼事?

  1. 出了問題需要找到是哪塊的代碼有問題
  2. 在原有的基礎上加入一些新的功能(也就是所謂的迭代)

面對重複的/繁瑣的非業務代碼:

  1. 如果程序出了問題,我們得看吧?誰也保證不了重複的代碼就沒有問題。
  2. 我們要想加一個新的功能,還得按原來的方式寫吧?代碼量會越來越多,越來越多….

上一期的「Mybatis」教程也講到了,我們的JDBC寫得好好的,運行的效率也是槓槓的。但是JDBC需要我們「自行」處理的細節太多了,我們需要在裡邊添加各種「重複」的代碼。

我們使用ORM框架,那麼我們就可以更加「專注」去實現本身的業務,ORM框架把「重複」的代碼都屏蔽掉,代碼維護起來就比JDBC要方便。

這應該是最通俗易懂的一篇Spring知識點總結了

Spring IOC 解決的是 對象管理和對象依賴的問題

Spring AOP 解決的是 非業務代碼抽取的問題

(這裡要是沒基礎的同學,可能看不太懂,下面再來解釋解釋一下應該就沒問題了)

Spring IOC

提到Spring IOC,隨便去網上一搜,我們就可以看到「依賴注入」「控制反轉」這兩個詞。

很多人都會試圖要把這兩個詞給解釋清楚,但是太難了,這兩個詞真的是太難給解釋清楚了。

這應該是最通俗易懂的一篇Spring知識點總結了

Spring IOC 解決的是對象管理和對象依賴的問題。本來我們的對象都是new出來的,而我們如果使用Spring 則把對象交給「IOC容器」來管理。

三歪這逼搞事情了。「依賴注入」和「控制反轉」都沒講,現在還來了個「IOC容器」。

「IOC容器」是什麼?我們可以理解為是一個「工廠」,我們把對象都交由這個「工廠」來管理,包括對象的創建和對象之間的依賴關係等等。等我們要用到對象的時候,就從這個「工廠」裡邊取出來。

「控制反轉」指的就是:本來是「由我們自己」new出來的對象,現在交給了IOC容器。把這個對象的「控制權」給「他方」了。「控制反轉」更多的是一種思想或者說是設計模式,把原有由自己掌控的事交給「別人」來處理。

「依賴注入」更多指的是「控制反轉」這個思想的實現方式:對象無需自行創建或管理它們的依賴關係,依賴關係將被「自動注入」到需要它們的對象當中去。

最簡單理解「依賴注入」和「控制反轉」:本來我們的對象都是「

由我們自己」new出來的,現在我們把這個對象的創建權限和對象之間的依賴關係交由「IOC容器」來管理。

悄悄話:我個人本身是不太喜歡琢磨每個詞的含義的,很多時候大佬們也很難解釋清楚。如果是初學的同學,也不用太糾結每個名詞的具體含義,深究下去也沒有太大的必要。

這應該是最通俗易懂的一篇Spring知識點總結了

現在問題又來了,為什麼我們要把對象給「IOC容器」來管理呢?要理解這個,我建議可以先去看看我寫過的「

工廠模式

理論上,我們可以把「IOC容器」也當做是一個「工廠」,使用IOC的好處就是:

  • 將對象集中統一管理,便於修改
  • 降低耦合度(調用方無需自己組裝,也無需關心對象的實現,直接從「IOC容器」取就好了)
這應該是最通俗易懂的一篇Spring知識點總結了

IOC 需要學什麼?

我們在使用Spring的時候,首先我們要學習的就是怎麼把對象交給「IOC容器管理」

Spring提供了四種方式:

  • 註解
  • XML
  • JavaConfig
  • 基於Groovy DSL配置

總的來說:我們以XML配置+註解來裝配Bean比較多,其中註解這種方式佔大部分。

把對象放到「IOC容器」了以後,對象與對象之間是有關係的,我們需要把對象之間的依賴告訴Spring,讓它來幫我們解決掉對象的依賴關係。

「對象之間的關係」別想得太複雜了。在日常開發中其實很多時候就是A對象裡邊有B對象的屬性而已。

這應該是最通俗易懂的一篇Spring知識點總結了

一般來說我們會通過構造器或者屬性(setting方法)的方式來注入對象的依賴

舉個例子:日常開發中,我們很多時候用@Component註解標識將對象放到「IOC容器」中,用@Autowired註解將對象注入

這應該是最通俗易懂的一篇Spring知識點總結了

下面這張圖就很好總結了以各種方式來

對Bean的定義和注入

這應該是最通俗易懂的一篇Spring知識點總結了

這應該是最通俗易懂的一篇Spring知識點總結了

Spring AOP

AOP:Aspect Object Programming 「面向切面編程」,聽起來是不是很牛逼。

Spring AOP主要做的事情就是:「把重複的代碼抽取,在運行的時候往業務方法上動態植入“切面類代碼”」

舉個例子,現在我們有以下的代碼:

這應該是最通俗易懂的一篇Spring知識點總結了

上面的代碼其實最核心的就一行代碼:「保存user對象到數據庫中」

<code>session.save(user);/<code>

我們的數據庫表肯定不止user一張表,對數據庫的增刪改也肯定不止add()方法一個。所以我們可以想象到:對數據庫的每次操作,都要寫「開啟事務」和「關閉事務」這種代碼。

這種代碼對我們來說是重複的,於是我們會想把這種代碼給「抽取」出來。

如果我們單純用OOP(面向對象)的思想去把代碼給優化掉,最終我們的效果可能是這樣的:

這應該是最通俗易懂的一篇Spring知識點總結了

即使這樣看起來代碼已經很少了,但我們細想一下會發現:update()/delete()方法同樣也會有aop.begin()這樣的重複代碼的。

我們想要「消滅」掉這些重複代碼,可以怎麼做?這個時候我們應該能想到「動態代理」,通過動態代理,我們可以把對象「增強」,將非業務代碼寫在要「增強」的邏輯上。

這應該是最通俗易懂的一篇Spring知識點總結了

完了以後,我們就可以通過「增強後的對象」去調用方法,最終屏蔽掉「重複代碼」

這應該是最通俗易懂的一篇Spring知識點總結了

效果可能會如下:

這應該是最通俗易懂的一篇Spring知識點總結了

上面是我們手動寫的代理來實現對「非業務代碼」的抽取,類似這樣的場景會有很多:比如我們要做權限控制,要對參數進行校驗等等。

Spring 支持了AOP,讓我們可以不用自己「手動」去寫代理對象,達到將「非業務代碼」的抽取的效果。

我們可以體驗一波Spring AOP是怎麼弄的,跟上面的對比對比:

這應該是最通俗易懂的一篇Spring知識點總結了

效果如下:

這應該是最通俗易懂的一篇Spring知識點總結了

總結

建議:在學習IOC之前,可以先看看「工廠模式」。在學習AOP之前,可以先看看「代理模式」

理解了「工廠模式」那就知道為什麼我們不再直接new對象,理解了「代理模式」,我們就知道Spring AOP的底層技術其實就是「動態代理」,這樣學習IOC和AOP的時候,就會輕鬆很多。

還要一點就是不要被「名詞」給嚇唬了,之前不懂某個技術的時候,聽別人講一些名詞,我對此完全不懂。那就可能會認為這個技術會很牛逼,其實等真正接觸下來,學習完了以後,其實發現也不過如此嘛。


分享到:


相關文章: